1. 概念
1.1 角色
- Builder(抽象建造者):给出一个抽象接口,以规范产品对象的各个组成成分的建造。
- ConcreteBuilder(具体建造者):它们在应用程序调用下创建产品的实例
- Director(导演者):调用具体建造者角色以创建产品对象。
它没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者。
- Product(产品):产品便是建造中的复杂对象。
1.2 类图
classDiagram
Product <.. ConcreteBuilder
Builder <|.. ConcreteBuilder
Director o--> Builder
class Product{
}
class Builder{
<<interface>>
+BuildPartA(param:Parameter)
+BuildPartB(param:Parameter)
}
class ConcreteBuilder{
+product:*Product
+BuildPartA(param:Parameter)
+BuildPartB(param:Parameter)
+GetProduct():Product
}
class Director{
+builder:Builder
+Construct(param:Parameter)
}
2. 代码示例
2.1 设计
- 定义一个产品
Product
,它包含Name
、PartA
、PartB
三个成员 - 定义一个抽象建造者
Builder
- 它的
CreateProduct()
方法来实例化一个产品 - 它的
BuildPartA()
、BuildPartB()
两个方法来装配产品
- 它的
- 定义具体建造者
ConcreteBuilder
- 它实现了抽象建造者的
CreateProduct()
、BuildPartA()
、BuildPartB()
三个方法 - 它有的
Get()
方法用来查询产品(我们这里简单写成打印产品实例)
- 它实现了抽象建造者的
- 定义导演者
Director
- 它关联了建造者
Builder
(我们简单写一个关联,当然你也可以写成聚合) - 它的
Construct()
方法调用建造者创建产品并装配
- 它关联了建造者
- 调用
- 实例化一个建造者
builder
, - 实例化一个导演者
director
,它关联建造者builder
- 用导演者
director
的Construct()
方法创建产品 - 使用建造者的
GetProduct()
方法查询产品
- 实例化一个建造者
2.2 代码
package main
import "fmt"
type Product struct {
Name string
PartA string
PartB string
}
type Builder interface {
CreateProduct(name string) *Product
BuildPartA(partA string, p *Product)
BuildPartB(partB string, p *Product)
}
type ConcreteBuilder struct {
}
func (c *ConcreteBuilder) CreateProduct(name string) *Product {
p := new(Product)
p.Name = name
return p
}
func (c *ConcreteBuilder) BuildPartA(partA string, p *Product) {
p.PartA = partA
}
func (c *ConcreteBuilder) BuildPartB(partB string, p *Product) {
p.PartB = partB
}
func (c *ConcreteBuilder) GetProduct(product *Product) {
fmt.Printf("%+v", product)
}
type Director struct {
builder Builder
}
func (d *Director) Construct(name string, partAInfo string, partBInfo string) *Product {
p := d.builder.CreateProduct(name)
d.builder.BuildPartA(partAInfo, p)
d.builder.BuildPartB(partBInfo, p)
return p
}
func main() {
builder := &ConcreteBuilder{}
director := &Director{builder: builder}
product := director.Construct("青龙刀", "刀头", "刀柄")
builder.GetProduct(product)
}
- 输出
&{Name:青龙刀 PartA:刀头 PartB:刀柄}
2.3 类图
classDiagram
Product <.. ConcreteBuilder
Builder <|.. ConcreteBuilder
Director o--> Builder
class Product{
+Name:String
+PartA:String
+PartB:String
}
class Builder{
<<interface>>
+ CreateProduct():*Product
+BuildPartA(p:string)
+BuildPartB(p:string)
}
class ConcreteBuilder{
+ CreateProduct():*Product
+BuildPartA(p:string)
+BuildPartB(p:string)
+GetProduct()
}
class Director{
+Builder builder
+Construct()
}