Builder Pattern

本文只要讨论了 Builder Pattern 建造者模式的 Go 实现

Builder Pattern 建造者模式

  • 建造者模式将复杂对象的构造及其表示形式分离开来,使得同样的构造过程可以创建不同的表示形式。

抽象接口实现

  • Builder: 创建一个产品(car)对象的各个部件的指定抽象接
  • Interface: 产品(car)功能的抽象接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package car

type Speed float64

const (
MPH Speed = 1
KPH = 1.60934
)

type Color string

const (
BlueColor Color = "blue"
GreenColor = "green"
RedColor = "red"
)

type Wheels string

const (
SportWheels Wheels = "sports"
SteelWheels = "steel"
)

type Builder interface {
Color(c Color) Builder
Wheels(w Wheels) Builder
TopSpeed(s Speed) Builder
Build() Interface
}

type Interface interface {
Drive() error
Stop() error
}

具体产品功能实现

  • 具体产品(car)需继承于 Interface
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package car

import "fmt"

type car struct {
Interface
color Color
wheels Wheels
speed Speed
}

func (c *car) Drive() error {
fmt.Printf("A %s car with %s tires is going at %f ", c.color, c.wheels, c.speed)
if c.speed == MPH {
fmt.Println("MPH")
} else {
fmt.Println("KPH")
}

return nil
}

func (c *car) Stop() error {
fmt.Println("The car stopped.")
return nil
}

具体建造者功能实现

  • 建造者(carBuilder)需继承于 Builder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package car

type carBuilder struct {
Builder
c *car
}

func NewCarBuilder() Builder {
cb := new(carBuilder)
cb.c = new(car)
return cb
}

func (cb *carBuilder) Color(c Color) Builder {
cb.c.color = c
return cb
}

func (cb *carBuilder) Wheels(w Wheels) Builder {
cb.c.wheels = w
return cb
}

func (cb *carBuilder) TopSpeed(s Speed) Builder {
cb.c.speed = s
return cb
}

func (cb *carBuilder) Build() Interface {
return cb.c
}

使用

1
2
3
4
5
6
7
8
9
10
11
func main() {
assembly := car.NewCarBuilder()

familyCar := assembly.Wheels(car.SportWheels).TopSpeed(50 * car.MPH).Color(car.RedColor).Build()
familyCar.Drive()
familyCar.Stop()

sportCar := assembly.Wheels(car.SteelWheels).TopSpeed(150 * car.MPH).Color(car.GreenColor).Build()
sportCar.Drive()
sportCar.Stop()
}