在Golang中您应该知道的构建器模式(设计模式01)

轻松构建复杂对象:Go中的Builder模式介绍

联系作者@:微信公众号,Medium,LinkedIn,Twitter

golang-builder-pattern(from github.com/MariaLetta/free-gophers-pack)|300

在 Go 语言中,设计模式是实现软件工程最佳实践的一种方式。其中,建造者模式(Builder Pattern) 是一种创建型设计模式,用于分步骤地创建复杂对象,同时避免构造函数中参数过多的情况。

建造者模式的核心概念

  1. 意图:将复杂对象的构建过程与其表示分离,使得相同的构建过程可以创建不同的表示。
  2. 适用场景
    • 当创建复杂对象需要分步骤进行时。
    • 当构造函数参数过多或参数组合导致对象的创建复杂时。
  3. 优点
    • 将对象的创建和表示分离,符合单一职责原则。
    • 更加灵活,便于扩展。
  4. 缺点
    • 增加了类的复杂性。
    • 对简单对象的创建可能略显多余。

建造者模式的结构

建造者模式主要包含以下几个部分:

  1. Product:需要创建的复杂对象。
  2. Builder:定义创建对象的接口,包含所有构建步骤。
  3. ConcreteBuilder:具体实现 Builder 接口,完成各部分构建。
  4. Director:指导构建过程,定义创建对象的顺序。

Go语言中的实现

以下是一个使用Go语言实现建造者模式的示例,以组装电脑为例:

1. 定义产品结构体

1
2
3
4
5
6
7
8
// 电脑结构,描述电脑的重要组件
type Computer struct {
CPU string
Memory string
Mainboard string
HardDisk string
GPU string
}

2. 定义建造者接口

1
2
3
4
5
6
7
8
9
// Builder 接口,定义生成实例的方法
type ComputerBuilder interface {
AddCPU()
AddMemory()
AddMainboard()
AddHardDisk()
AddGPU()
GetComputer() Computer
}

3. 实现具体建造者

办公型电脑建造者

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
type OfficeModelBuilder struct {
Computer
}

func (ob *OfficeModelBuilder) AddCPU() {
ob.CPU = "Intel-i3"
}

func (ob *OfficeModelBuilder) AddMemory() {
ob.Memory = "8G"
}

func (ob *OfficeModelBuilder) AddMainboard() {
ob.Mainboard = "B460"
}

func (ob *OfficeModelBuilder) AddHardDisk() {
ob.HardDisk = "256G HDD"
}

func (ob *OfficeModelBuilder) AddGPU() {
ob.GPU = "Intel HD630"
}

func (ob *OfficeModelBuilder) GetComputer() Computer {
return Computer{
CPU: ob.CPU,
Memory: ob.Memory,
Mainboard: ob.Mainboard,
HardDisk: ob.HardDisk,
GPU: ob.GPU,
}
}

游戏型电脑建造者

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
type GameModelBuilder struct {
Computer
}

func (gb *GameModelBuilder) AddCPU() {
gb.CPU = "Intel-i9"
}

func (gb *GameModelBuilder) AddMemory() {
gb.Memory = "32G"
}

func (gb *GameModelBuilder) AddMainboard() {
gb.Mainboard = "X460"
}

func (gb *GameModelBuilder) AddHardDisk() {
gb.HardDisk = "512G SSD, 1T HDD"
}

func (gb *GameModelBuilder) AddGPU() {
gb.GPU = "NVIDIA GTX3090"
}

func (gb *GameModelBuilder) GetComputer() Computer {
return Computer{
CPU: gb.CPU,
Memory: gb.Memory,
Mainboard: gb.Mainboard,
HardDisk: gb.HardDisk,
GPU: gb.GPU,
}
}

4. 指挥者实现

1
2
3
4
5
6
7
8
9
10
11
12
13
type Director struct {
builder ComputerBuilder
}

// 建造方法,定义步骤及顺序
func (d *Director) Build() Computer {
d.builder.AddCPU()
d.builder.AddMemory()
d.builder.AddMainboard()
d.builder.AddHardDisk()
d.builder.AddGPU()
return d.builder.GetComputer()
}

5. 测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
func main() {
// 办公型电脑建造者
officeBuilder := &OfficeModelBuilder{}

// 指挥者实例化并传入具体建造者
director := Director{officeBuilder}

computer1 := director.Build()
fmt.Printf("办公型主机配置:%v \n", computer1)

// 游戏型电脑建造者
gameBuilder := &GameModelBuilder{}

// 切换指挥者的构建器
director.builder = gameBuilder

computer2 := director.Build()
fmt.Printf("游戏型主机配置:%v \n", computer2)
}
// output
办公型主机配置:{Intel-i3 8G B460 256G HDD Intel HD630}
游戏型主机配置:{Intel-i9 32G X460 512G SSD, 1T HDD NVIDIA GTX3090}

6. Golang 实现的相关思考

以上实现参考了Java 的实现方法,但是 Golang 应该有自己的特色。Go Is Not Java

  1. 去掉 Director
    在 Go 的实现中,Director 并不是必需的。将构建逻辑直接放在建造器函数里(OfficeComputerBuilderGameComputerBuilder)更符合 Go 的简单直接风格。

  2. 函数链式调用:
    GenericBuilder 使用链式方法(方法返回自身),方便一步步构建对象。

  3. 更加清晰的职责划分:
    GenericBuilder 是一个通用建造器,而具体的 OfficeComputerBuilderGameComputerBuilder 负责生成具体的电脑配置。

  4. 避免过度设计:
    Go 提倡简洁,不必强求像 Java 那样使用复杂的设计模式实现。

你也可以参考文章: Design patterns in Golang — The Builder | by Surya Reddy | Medium

总结

  1. 建造者模式通常适用于有多个构造器参数或者需要较多构建步骤的场景。使用建造者模式可以精简构造器参数的数量,让构建过程更有条理。
  2. 可以为同一个产品提供多个不同的实现。比如,在上面的代码中,为Computer类型创建了两个不同的实现:通过NewOfficeModelBuilder构建的 office computer,以及通过NewGameModelBuilder构建的 game computer
  3. 可以应用于构建过程不允许被中断的场景。仍然参考刚才的代码,Computer类型的对象要么彻底完成,要么压根没有创建,不会存在中间状态,这是因为struct director封装了相应的过程,中间状态仅存在于ConcreteBuilder中。

更多该系列文章,参考medium链接:

https://wesley-wei.medium.com/list/you-should-know-in-golang-e9491363cd9a

English post: https://programmerscareer.com/golang-builder-pattern/
作者:微信公众号,Medium,LinkedIn,Twitter
发表日期:原文在 2024-11-17 17:53 时创作于 https://programmerscareer.com/zh-cn/golang-builder-pattern/
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证

在Golang你应该知道的工厂模式(设计模式02) 启迪周刊-001:如何理解代码和对投资的认知

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×