生成器模式 也叫建造者模式或者构建者模式。生成器模式是一种创建型设计模式,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。
生成器模式解决的问题是:创建对象时,初始化步骤复杂,构造函数参数很多。使用该模式能够简化初始化的过程。
实现步骤:
- 清晰地定义通用步骤, 确保它们可以制造所有形式的产品。在基本生成器接口中声明这些步骤。
- 为每个形式的产品创建具体生成器类, 并实现其构造步骤。
- 考虑创建主管类。 它可以使用同一生成器对象来封装多种构造产品的方式。
- 客户端代码会同时创建生成器和主管对象。 构造开始前, 客户端必须将生成器对象传递给主管对象。 通常情况下, 客户端只需调用主管类构造函数一次即可。 主管类使用生成器对象完成后续所有制造任务。 还有另一种方式, 那就是客户端可以将生成器对象直接传递给主管类的制造方法。
- 只有在所有产品都遵循相同接口的情况下, 构造结果可以直接通过主管类获取。 否则, 客户端应当通过生成器获取构造结果。
优点:
- 你可以分步创建对象, 暂缓创建步骤或递归运行创建步骤。
- 生成不同形式的产品时, 你可以复用相同的制造代码。
- 单一职责原则,你可以将复杂构造代码从产品的业务逻辑中分离出来
缺点:
- 由于该模式需要新增多个类,因此代码整体复杂程度会有所增加。
下面的实例代码是根据 生成器模式 这篇文章的讲解实现的。
package main
import "fmt"
type house struct {
wall string
pool bool
tree bool
}
func (h *house) show() {
fmt.Printf("wall: %s, pool: %v, tree: %v\n", h.wall, h.pool, h.tree)
}
type builder interface {
reset()
setPool()
setTree()
}
type woodHouseBuilder struct{ house }
func (b *woodHouseBuilder) setPool() {
b.pool = true
}
func (b *woodHouseBuilder) setTree() {
b.tree = true
}
func (b *woodHouseBuilder) reset() {
b.wall = "wood"
b.pool = false
b.tree = false
}
func (b *woodHouseBuilder) get() house {
return b.house
}
type stoneHouseBuilder struct{ house }
func (b *stoneHouseBuilder) setPool() {
b.pool = true
}
func (b *stoneHouseBuilder) setTree() {
b.tree = true
}
func (b *stoneHouseBuilder) reset() {
b.wall = "stone"
b.pool = false
b.tree = false
}
func (b *stoneHouseBuilder) get() house {
return b.house
}
type director struct {
b builder
}
func (d *director) connectBuilder(b builder) {
d.b = b
}
func (d *director) changeBuilder(b builder) {
d.b = b
}
func (d *director) make(t string) {
d.b.reset()
if t == "simple" {
} else {
d.b.setPool()
d.b.setTree()
}
}
func main() {
detor := director{}
woodBuilder := woodHouseBuilder{}
detor.connectBuilder(&woodBuilder)
detor.make("all")
woodHouse := woodBuilder.get()
woodHouse.show() // wall: wood, pool: true, tree: true
stoneBuilder := stoneHouseBuilder{}
detor.changeBuilder(&stoneBuilder)
detor.make("simple")
stoneHouse := stoneBuilder.get()
stoneHouse.show() // wall: stone, pool: false, tree: false
}
上面的例子,实现生成器模式的关键在于:
- 明确
builder的作用:实现具体的初始化操作 - 明确
director的作用:与特定的builder关联,对builder的初始化步骤进行选择(调用),实现builder关联的对象(上面的例子是house)的创建 - 通过
director生成的对象进行批量生成,上面的例子通过builder的get方法进行获取