建造者模式(Builder Design Pattern)
建造者模式使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式。还可以通过返回自身进行链式调用。
如经常使用的SQLBuilder就属于这种,一步步构建成一个完整的SQL:
err := engine.Where(builder.NotIn("a", 1, 2).And(builder.In("b", "c", "d", "e"))).Find(&users)
// SELECT id, name ... FROM user WHERE a NOT IN (?, ?) AND b IN (?, ?, ?)
建造者模式由产品角色、抽象建造者、具体建造者:
- 产品角色:由多个部件组成的对象,由具体建造者来创建各个部件。
- 抽象建造者:提供创建各个部件的抽象接口。
- 具体建造者:实现抽象建造者的接口,完成各部件的具体创建方法。
有些文章中写到还需要一个Director指挥者,其实没有必要,我们调用的时候就相当于一个指挥者,具体怎么使用还要看使用场景,设计模式的使用要灵活多变。
代码示例
这里仍然用组装一台计算机的例子说明:
package builder
type Computer struct {
CPU string
GPU string
Board string
}
type ComputerBuilder interface {
SetCPU(name string) ComputerBuilder
SetGPU(name string) ComputerBuilder
SetBoard(name string) ComputerBuilder
Build() Computer
}
type MacbookBuilder struct {
cpu, gpu, board string
}
func (m *MacbookBuilder) SetCPU(name string) ComputerBuilder {
m.cpu = name
return m
}
func (m *MacbookBuilder) SetGPU(name string) ComputerBuilder {
m.gpu = name
return m
}
func (m *MacbookBuilder) SetBoard(name string) ComputerBuilder {
m.board = name
return m
}
func (m *MacbookBuilder) Build() Computer {
return Computer{CPU: m.cpu, GPU: m.gpu, Board: m.board}
}
调用方式:
var builder ComputerBuilder = &MacbookBuilder{}
var computer Computer = builder.SetCPU("intel").SetGPU("nvidia").SetBoard("asus").Build()
fmt.Printf("%+v\n", computer)