设计模式-建造者模式

建造者模式(Builder Pattern):将复杂对象的创建和表示分离,使同样的构建过程可以创建不同的表示。

进一步说,建造者隐藏了产品是如何组装的,使建造代码和表示代码分离。建造对象时 构件顺序稳定 的情况下,不管每一步具体怎么变都可以适用。

builder.png

简单说,建造者模式将需要一系列动作才能完成的事固化下来,并定义了一个Director给客户端使用。还是很抽象的话,想想如何把大象装进冰箱:

  1. 打开冰箱门
  2. 把大象装进去
  3. 关上冰箱门

这个步骤比较简单,但如果细化一下:买冰箱、接通电源、买大象、清洗大象……很可能就会有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来创建产品(这里我偷懒了,并没返回冻肉这个产品,而仅仅是输出),无需关心具体实现步骤,实现代码解耦。

应用场景

  1. 当生成的对象内部结构复杂时(需要很多步骤时)
  2. 需要向客户隐藏产品内部实现步骤时