go 生成器模式的具体使用
作者:ldxxxxll
生成器是一种创建型设计模式,使你能够分步骤创建复杂对象,本文主要介绍了go生成器模式的具体使用,具有一定的参考价值,感兴趣的可以了解一下
生成器模式
生成器模式建议将对象构造代码从产品类中抽取出来, 并将其放在一个名为生成器的独立对象中。
模型说明
- 生成器 (Builder) 接口声明在所有类型生成器中通用的产品构造步骤。
- 具体生成器 (Concrete Builders) 提供构造过程的不同实现。 具体生成器也可以构造不遵循通用接口的产品。
- 产品 (Products) 是最终生成的对象。 由不同生成器构造的产品无需属于同一类层次结构或接口。
- 主管 (Director) 类定义调用构造步骤的顺序, 这样你就可以创建和复用特定的产品配置。
- 客户端 (Client) 必须将某个生成器对象与主管类关联。 一般情况下, 你只需通过主管类构造函数的参数进行一次性关联即可。 此后主管类就能使用生成器对象完成后续所有的构造任务。 但在客户端将生成器对象传递给主管类制造方法时还有另一种方式。 在这种情况下, 你在使用主管类生产产品时每次都可以使用不同的生成器。
优缺点
1.优点
- 你可以分步创建对象,暂缓创建步骤或递归运行创建步骤。
- 生成不同形式的产品时,你可以复用相同的制造代码。
- *单一职责原则:*你可以将复杂构造代码从产品的业务逻辑中分离出来。
2.缺点
- 由于该模式需要新增多个类,因此代码整体复杂程度会有所增加。
使用场景
- 使用生成器模式可避免“重叠构造函数(telescoping constructor)”的出现。
- 当你希望使用代码创建不同形式的产品(例如石头或木头房屋)时,可使用生成器模式。
- 使用生成器构造组合树或其他复杂对象。
参考代码
使用建造普通房子以及别墅来模拟
iBuilder.go: 生成器接口
package main type IBuilder interface { setWindowType() setDoorType() setNumFloor() getHouse() House } func getBuilder(builderType string) IBuilder { if builderType == "normal" { return newNormalBuilder() } if builderType == "villa" { return newVillaBuilder() } 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, } }
villaBuilder.go: 别墅生成器
package main type VillaBuilder struct { windowType string doorType string floor int } func newVillaBuilder() *VillaBuilder { return &VillaBuilder{} } func (b *VillaBuilder) setWindowType() { b.windowType = "Snow Window" } func (b *VillaBuilder) setDoorType() { b.doorType = "Snow Door" } func (b *VillaBuilder) setNumFloor() { b.floor = 1 } func (b *VillaBuilder) 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") villaBuilder := getBuilder("villa") director := newDirector(normalBuilder) normalHouse := director.buildHouse() fmt.Printf("Normal House Door Type: %s\n", normalHouse.doorType) fmt.Printf("Normal House Window Type: %s\n", normalHouse.windowType) fmt.Printf("Normal House Num Floor: %d\n", normalHouse.floor) director.setBuilder(villaBuilder) villa := director.buildHouse() fmt.Printf("\nIgloo House Door Type: %s\n", villa.doorType) fmt.Printf("Igloo House Window Type: %s\n", villa.windowType) fmt.Printf("Igloo House Num Floor: %d\n", villa.floor) }
output:
Normal House Door Type: Wooden Door
Normal House Window Type: Wooden Window
Normal House Num Floor: 2Igloo House Door Type: Snow Door
Igloo House Window Type: Snow Window
Igloo House Num Floor: 1
到此这篇关于go 生成器模式的具体使用的文章就介绍到这了,更多相关go 生成器模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!