【Go-设计模式】建造者模式 详解

概念:
- 建造者模式(Builder Pattern) 又叫 生成器模式,是一种 对象构建模式
它可以将 复杂对象的建造过程 抽象出来,使这个 抽象过程 的 不同实现方法 可以构造出 不同表现(属性) 的对象 - 建造者模式 是 一步一步 创建一个复杂的对象,
它允许用户只通过 指定 复杂对象 的 类型 和 内容 就可以构建它们,用户不需要知道内部的 具体构建细节

UML:

建造者模式中,有如下四种角色:
- 抽象建造者(Builder):
该绝是用于规范产品的各个组成部分,并进行抽象,一般独立于应用程序的逻辑。 - 具体建造者(Concrete Builder):
该角色实现抽象建造者中定义的所有方法,并且返回一个组件好的产品实例。 - 产品(Product):
该角色是建造者中的复杂对象,一个系统中会有多个产品类,这些产品类不一定有共同的接口,可以是完成不相关的。 - 指挥者(Director):
该角色负责安排已有模块的顺序,然后告诉Builder开始建造。
它主要有两个作用:
- 隔离 Client 与 对象的生产过程
- 负责控制 对象的生产过程
示例:
产品类:
type Product string
抽象建造者:
type Builder interface { // model构造器 接口约定
BuildPart1()
BuildPart2()
BuildPart3()
GetResult() Product
}
具体建造者:
具体建造者1:
type BuilderModel1 struct {
result []string
}
func (this *BuilderModel1) BuildPart1() {
this.result = append(this.result, "model1 组件1拼接成功!")
}
func (this *BuilderModel1) BuildPart2() {
this.result = append(this.result, "model1 组件2拼接成功!")
}
func (this *BuilderModel1) BuildPart3() {
this.result = append(this.result, "model1 组件3拼接成功!")
}
func (this *BuilderModel1) GetResult() Product {
var resultShow string
for _, partFun := range this.result {
resultShow += fmt.Sprintf("%v /n", partFun)
}
return Product(resultShow)
}
具体建造者2:
type BuilderModel2 struct {
result []string
}
func (this *BuilderModel2) BuildPart1() {
this.result = append(this.result, "model2 组件1拼接成功!")
}
func (this *BuilderModel2) BuildPart2() {
this.result = append(this.result, "model2 组件2拼接成功!")
}
func (this *BuilderModel2) BuildPart3() {
this.result = append(this.result, "model2 组件3拼接成功!")
}
func (this *BuilderModel2) GetResult() Product {
var resultShow string
for _, partFun := range this.result {
resultShow += fmt.Sprintf("%v /n", partFun)
}
return Product(resultShow)
}
指挥者
type Director struct { // 指挥者
builder Builder
}
func NewDirector(builder Builder) *Director {
return &Director{
builder: builder,
}
}
func (this *Director) Construct(resultType int64) Product {
if resultType == 1 {
this.builder.BuildPart1()
this.builder.BuildPart2()
} else if resultType == 2 {
this.builder.BuildPart2()
this.builder.BuildPart3()
} else {
this.builder.BuildPart1()
this.builder.BuildPart3()
}
return this.builder.GetResult()
}
测试:
package main
import (
"DemoProject/design/base23" // 根据自己的项目路径定制
"fmt"
)
func main() {
model1 := base23.BuilderModel1{}
director := base23.NewDirector(&model1)
fmt.Printf(string(director.Construct(2)))
}
注意事项:
- Client 不必知道 产品内部组成的细节,
将 产品本身 与 产品的创建过程 解耦,使得 相同的创建过程 可以创建 不同的产品对象 - 每一个 具体建造者 都 相对独立,而 与其他的具体建造者无关,
因此可以很方便地 替换具体建造者 或 增加新的具体建造者,
用户使用 不同的具体建造者 即可得到 不同的产品对象 - 可以更加精细地控制 产品的创建过程
将 复杂产品的创建步骤 分解在 不同的方法中,使得 创建过程 更加清晰, 也更方便使用程序来控制创建过程 - 增加新的具体建造者 无须修改原有类库的代码,
指挥者类 针对 抽象建造者类编程,系统扩展方便,符合“开闭原则” - 建造者模式所创建的产品一般具有 较多的共同点,其组成部分相似,
如果产品之间的 差异性很大,则 不适合 使用建造者模式,因此其使用范围受到一定的限制 - 如果产品的 内部变化复杂,可能会导致需要 定义很多具体建造者类 来实现这种变化,导致系统变得很庞大,
因此在这种情况下,要考虑是否选择建造者模式

浙公网安备 33010602011771号