Go 设计模式之工厂方法模式

介绍

工厂方法模式要求定义一个方法,所有对象都通过该方法创建,子类可以重写该方法更改创建对象的属性。

组成

  • 抽象工厂角色: 这是工厂方法模式的核心,它与应用程序无关。是具体工厂角色必须实现的接口或者必须继承的父类
  • 具体工厂角色:它含有和具体业务逻辑有关的代码。
  • 抽象产品角色:它是具体产品继承的父类或者是实现的接口。
  • 具体产品角色:具体工厂角色所创建的对象就是此角色的实例。

示例介绍

我们以造抢为例,这里我们定义一个枪支工厂gun­Factory,用来制造枪支。这里我们的工厂可以制造两种枪支ak47m16,每只枪都有名字(name)和火力值(power)属性。

我们可以为每把枪单独设值名字和火力值,并且可以获取枪的名字和火力值

代码示例

抽象工厂角色:枪拥有的接口

type Gun interface {
    setName(name string)
    setPower(power int)
    getName() string
    getPower() int
}

抽象产品角色:枪的通用设置

type gun struct {
    name  string
    power int
}

func (g *gun) setName(name string) {
    g.name = name
}

func (g *gun) setPower(power int) {
    g.power = power
}

func (g *gun) getName() string {
    return g.name
}

func (g *gun) getPower() int {
    return g.power
}

具体工厂角色:建造工厂

func gunFactory(ty string) Gun {
    switch ty {
    case "ak47":
        return newAk47()
    case "m16":
        return newM16()
    }
    return nil
}

具体产品角色:ak47

type ak47 struct {
    gun
}

func newAk47() Gun {
    return &ak47{
        gun: gun{
            name:  "ak47",
            power: 3,
        },
    }
}

具体产品角色:m16

type m16 struct {
    gun
}

func newM16() Gun {
    return &m16{
        gun: gun{
            name:  "m16",
            power: 4,
        },
    }
}

至此我们的枪支工厂已经组建完成,可以生产两种类型的枪支,并且能获取和设置枪的火力和名字

接下来我们开始生产枪支,并调节火力吧!

func Test_gunFactory(t *testing.T) {
    ak47 := gunFactory("ak47")
    name := ak47.getName()
    power := ak47.getPower()
    assert.Equal(t, name, "ak47")
    assert.Equal(t, power, 3)
    ak47.setPower(5)
    power = ak47.getPower()
    assert.Equal(t, power, 5)
    m16 := gunFactory("m16")
    assert.Equal(t, m16.getPower(), 4)
}

发表评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注

Captcha Code