设计模式-建造者模式
2012 年 7 月 11 日
建造者模式(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
来创建产品(这里我偷懒了,并没返回冻肉这个产品,而仅仅是输出),无需关心具体实现步骤,实现代码解耦。