建造者模式

927 阅读2分钟

设计模式是经过验证,用于解决在特定环境下、重复出现、特定问题的解决方案。

github: github.com/zexho994/go…

背景

既然叫建造者模式,那么就用造房子为例。

房地产公司负责盖饭,有两种房子

别墅

type villa struct {
	walls   int
	windows int
	doors   int
}

func (this villa) setWalls(nums int) {
	this.walls = nums
	// 建造villa的wall
}

func (this villa) setWindows(nums int) {
	this.walls = nums
	// 建造villa的windows
}

func (this villa) setDoors(nums int) {
	this.walls = nums
	// 建造villa的doors
}

func (this villa) build() {
	// build the villa
}

公寓

type apartment struct {
	walls   int
	windows int
	doors   int
}

func (this apartment) setWalls(nums int) {
	this.walls = nums
	// 建造apartment的wall
}

func (this apartment) setWindows(nums int) {
	this.walls = nums
	// 建造apartment的windows
}

func (this apartment) setDoors(nums int) {
	this.walls = nums
	// 建造apartment的doors
}

func (this apartment) build() {
	// build the apartment
}

客户端使用的逻辑如:

func client() {
	v := villa{}
	v.setDoors(2)
	v.setWindows(4)
	v.setWalls(8)
	v.build()

	a := apartment{}
	a.setDoors(1)
	a.setWindows(2)
	a.setWalls(4)
	a.build()
}

可以发现,房子的建造过程是存在相同步骤的,建造者模式的作用之一就是让这些相同的步骤单独出来,本质上就是将算法的实现与算法的装配进行分离。

解决方案

建造者模式有两个重要的角色,Builder 和 Director

  • Builder负责定义出算法的方法,由Builder的字类去实现算法的细节。
  • Director负责定义算法的装配逻辑,客户端负责调用Director的make()方法即可

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/ed53a691-a3b3-4f0f-ab4e-8a9578bcea54/Untitled.png

Builder - 定义房子的接口类

type House interface {
	setWalls(nums int)
	setWindows(nums int)
	setDoors(nums int)
}

Director - 定义房子的建造逻辑

type Director struct {
	builder Builder
}

func (this Director) setBuilder(b Builder) {
	this.builder = b
}

func (this Director) buildPart(wa, do, wi int) {
	this.builder.setWalls(wa)
	this.builder.setDoors(do)
	this.builder.setWindows(wi)
}

新的客户端调用

func main() {
	dir := Director{}

	// 执行别墅的构建
	dir.setBuilder(villa{})
	dir.buildPart(1, 2, 3)

	// 执行公寓的构建
	dir.setBuilder(apartment{})
	dir.buildPart(2, 4, 8)
}

模式讲解

建造者模式的本质:分离算法的逻辑与使用

这样的好处是松耦合,例如以下场景:

  • 当需要改变算法的使用流程时,只需要修改Director类的构建方法就好
  • 当需要修改制定算法的实现细节时候,只需要修改对应生成器的逻辑就好

这样就将与客户端接触的Director与内部细节的Builder分离了。

建造者设计模式(生成器模式)

很生动的例子