设计模式-建造者模式
建造者模式(Builder Pattern):将复杂对象的创建和表示分离,使同样的构建过程可以创建不同的表示。
进一步说,建造者隐藏了产品是如何组装的,使建造代码和表示代码分离。建造对象时 构件顺序稳定 的情况下,不管每一步具体怎么变都可以适用。
简单说,建造者模式将需要一系列动作才能完成的事固化下来,并定义了一个Director给客户端使用。还是很抽象的话,想想如何把大象装进冰箱:
- 打开冰箱门
- 把大象装进去
- 关上冰箱门
这个步骤比较简单,但如果细化一下:买冰箱、接通电源、买大象、清洗大象……很可能就会有300个步骤。建造者模式则提供了一系列行为的集合,保证以后有把山羊装进冰箱这样的需求时候不会遗漏某个步骤(想想KFC、麦当劳生产食品的步骤,其实是建造者模式不错的例子)。
代码实现如下:
package main
import (
"fmt"
)
// 把xx装进冰箱
type inFridge interface {
openDoor()
putInFridge()
closeDoor()
}
type meat struct {
name string
}
func (m meat) openDoor() {
fmt.Println("Open the Door!")
}
func (m meat) closeDoor() {
fmt.Println("Close the Door!")
}
type pig struct {
meat
}
func (p pig) putInFridge() {
fmt.Printf("Put %s in fridge \n",p.name)
}
type chicken struct {
meat
}
func (c chicken) putInFridge() {
fmt.Printf("Kill the %s \n",c.name)
fmt.Printf("Put %s in fridge \n",c.name)
}
type director struct {
i inFridge
}
func (d director) createMeat() {
d.i.openDoor()
d.i.putInFridge()
d.i.closeDoor()
}
func main() {
p := pig{meat:meat{name:"pig"}}
c := chicken{meat:meat{name:"chicken"}}
d := director{i:p}
d.createMeat()
d2 := director{i:c}
d2.createMeat()
}
代码很简单,定义了meat
基类和inFridge
接口,并在pig
以及chicken
实现。把猪肉放进冰箱和把鸡肉放进冰箱步骤是一样的,而放鸡肉时候要多进行一步“杀鸡”,所以使用建造者模式时,到底将步骤抽象提取出多少步则是需要权衡的。然后客户端通过使用director
来创建产品(这里我偷懒了,并没返回冻肉这个产品,而仅仅是输出),无需关心具体实现步骤,实现代码解耦。
应用场景
- 当生成的对象内部结构复杂时(需要很多步骤时)
- 需要向客户隐藏产品内部实现步骤时