建造者设计模式
建造者模式也叫生成器模式。
生成器模式是一种创建型设计模式, 目标是将复杂对象的构造与其表示分离,以便相同的构造过程可以创建不同的表示。
案例
iglooBuilder冰屋生成器与 normalBuilder普通房屋生成器可建造不同类型房屋, 即 igloo冰屋和 normalHouse普通房屋 。 每种房屋类型的建造步骤都是相同的。 主管 (可选) 结构体可对建造过程进行组织。
iBuilder.go: 生成器接口
package main
type IBuilder interface {
setWindowType()
setDoorType()
setNumFloor()
getHouse() House
}
func getBuilder(builderType string) IBuilder {
if builderType == "normal" {
return newNormalBuilder()
}
if builderType == "igloo" {
return newIglooBuilder()
}
return nil
}
normalBuilder.go: 具体生成器
package main
type NormalBuilder struct {
windowType string
doorType string
floor int
}
func newNormalBuilder() *NormalBuilder {
return &NormalBuilder{}
}
func (b *NormalBuilder) setWindowType() {
b.windowType = "Wooden Window"
}
func (b *NormalBuilder) setDoorType() {
b.doorType = "Wooden Door"
}
func (b *NormalBuilder) setNumFloor() {
b.floor = 2
}
func (b *NormalBuilder) getHouse() House {
return House{
doorType: b.doorType,
windowType: b.windowType,
floor: b.floor,
}
}
iglooBuilder.go: 具体生成器
package main
type IglooBuilder struct {
windowType string
doorType string
floor int
}
func newIglooBuilder() *IglooBuilder {
return &IglooBuilder{}
}
func (b *IglooBuilder) setWindowType() {
b.windowType = "Snow Window"
}
func (b *IglooBuilder) setDoorType() {
b.doorType = "Snow Door"
}
func (b *IglooBuilder) setNumFloor() {
b.floor = 1
}
func (b *IglooBuilder) getHouse() House {
return House{
doorType: b.doorType,
windowType: b.windowType,
floor: b.floor,
}
}
house.go: 产品
package main
type House struct {
windowType string
doorType string
floor int
}
director.go: 主管
package main
type Director struct {
builder IBuilder
}
func newDirector(b IBuilder) *Director {
return &Director{
builder: b,
}
}
func (d *Director) setBuilder(b IBuilder) {
d.builder = b
}
func (d *Director) buildHouse() House {
d.builder.setDoorType()
d.builder.setWindowType()
d.builder.setNumFloor()
return d.builder.getHouse()
}
main.go: 客户端代码
package main
import "fmt"
func main() {
normalBuilder := getBuilder("normal")
director := newDirector(normalBuilder)
normalHouse := director.buildHouse()
}
总结
本案例buildHouse()的顺序是固定的,也就是说 igloo冰屋和 normalHouse普通房屋 的建造顺序是一样的。
如果不同的对象有不同的构建顺序。在director中构建。
建造者模式的角色:
生成器、具体生成器、产品、导演(director,可选)、客户端。
导演类起到封装的作用,避免高层模块深入到建造者内部的实现类。
建造者关注的是零件类型和装配工艺(顺序)。工厂方法重点是创建。
建造者模式最主要的功能是基本方法的调用顺序安排。
使用场景
- 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
- 当开发者希望创建不同形式的产品时,可以使用建造者模式。
- 如果需要使用构造函数,并且构造函数的参数很多,可以使用建造者模式(链式调用)。
优点
- 在建造者模式中,产品内部组成的细节对客户端不可见,将产品的创建过程和产品解耦。
- 在生成器模式中,每个具体生成器都相对独立,方便扩展。
- 将复杂的产品创建步骤分解在不同的方法中,使创建过程更清晰。
缺点
- 在生成器模式中,需要为不同类型的产品创建单独的具体生成器,因此代码量较大。