Simple Factory Pattern(简单工厂模式)
简单工厂模式属于创建型模式,不会对外暴露创建对象的逻辑,并且我们通过一个共同的接口来创建不同的对象。
形象地理解就是,使用同一个工厂,可以创建出不同的产品,比如玩具工厂,可以生产出不同的玩具。
五大要素
来看看简单工厂模式的五大要素:
- 模式名称:简单工厂模式
- 目的(What):定义一个创建具体对象的工厂,有工厂调用者自己决定创建哪个对象
- 解决的问题(Why):当我们明确知道不同地条件下需要创建不同的对象时,使用这种模式
- 解决方案(How):通过
NewFactory()
生成一个工厂Factory
对象,提供了New()
方法,返回该工厂具体生产的工厂类,New()
方法接收给定的参数,通过不同的参数返回不同的工厂类对象。 - 解决效果:
- 优点:
- 一个调用者想要创建一个对象,只需要知道它的名称就可以了
- 扩展性高,如果想要新增加一个产品,只需要扩展一个工厂类对象
- 屏蔽产品的具体实现,调用者只关心产品的接口
- 缺点:
- 每种工厂新增加一个工厂类时,就要对工厂
Factory
对象的New()
方法进行修改,需要多判断一种参数 - 每次需要新添加一个工厂时,比如现在是玩具厂,需要添加一个针织厂,就需要新建一个工厂对象和一些工厂类对象,使得系统中类的个数成倍在增加,在一定程度上增加了系统的复杂度
- 每种工厂新增加一个工厂类时,就要对工厂
- 优点:
Go实现简单工厂模式
场景
现在有一个玩具厂,我们想要生产一堆玩具,玩具包括拼图(puzzle)和弹珠(marble),我们可以根据自己的需要选择生产拼图还是弹珠。
simple_factory.go
:
package simpleFactory
import "fmt"
const (
puzzle = iota
marble
unsupported
)
// 玩具工厂
type ToyFactory struct {}
// New根据传入的参数生产不同的玩具
func (t *ToyFactory) New(typ int) Toy{
switch typ {
case puzzle:
return new(Puzzle)
case marble:
return new(Marble)
default:
fmt.Println("unsupported type of toy")
return nil
}
}
// 玩具接口,需要实现一个Play方法
type Toy interface {
Play()
}
// 拼图玩具,实现了玩具接口
type Puzzle struct {}
func (*Puzzle) Play() {
fmt.Println("playing puzzle")
}
// 弹珠玩具,实现了玩具接口
type Marble struct {}
func (*Marble) Play() {
fmt.Println("playing marble")
}
simple_factory_test.go
:
package simpleFactory
import (
"testing"
)
func TestSimpleFactory(t *testing.T) {
factory := new(ToyFactory)
toy1 := factory.New(puzzle)
toy1.Play()
toy2 := factory.New(marble)
toy2.Play()
toy3 := factory.New(unsupported)
if toy3 != nil {
t.Fail()
}
}
执行测试结果:
=== RUN TestSimpleFactory
playing puzzle
playing marble
unsupported type of toy
--- PASS: TestSimpleFactory (0.00s)
PASS