Go语言设计模式:建造者模式详解
文章目录
- 一、建造者模式概述
- 1.1 建造者简介
- 1.2 建造者模式优缺点
- 1.3 两种Go实现的对比与选择
 
- 二、案例:实现「手机(Phone)」的建造者模式
- 1.1 定义产品结构体(Phone)
- 1.2 定义建造者接口(PhoneBuilder)
- 1.3 实现具体建造者
- 1.4 定义指挥者(Director)
- 1.5 客户端调用
- 1.6 完整代码与执行结果
 
- 三、Go风格建造者模式
 
一、建造者模式概述
1.1 建造者简介
建造者模式(Builder Pattern) 是一种创建型设计模式,核心是将复杂对象的构建过程与表示分离,使得同样的构建步骤可以生成不同配置的对象。
核心思想:将一个复杂对象的构建过程与它的表示分离。用户只需指定建造的类型,而不需要关心其内部具体的构建细节。
适用场景:当对象包含多个部件、构建步骤固定但具体配置灵活时(如汽车、文档、配置文件等),可通过建造者模式简化创建逻辑,避免代码冗余。
1.2 建造者模式优缺点
优点
- 分步创建:你可以分步骤创建对象,对构建过程施加更精细的控制。
- 代码复用:相同的构建代码可以构建出不同的对象表示。
- 解耦:将产品的构造代码与表示代码分离,使得客户端代码无需知道产品内部的组成细节。
- 对复杂对象友好:对于包含大量参数和复杂初始化逻辑的对象,建造者模式可以极大地提高代码的可读性和可维护性。
缺点
- 代码量增加:需要创建多个新的类(Director、Builder、ConcreteBuilder),增加了代码的复杂度。
- 适用范围有限:如果产品之间的差异性很大,不适合使用建造者模式。它更适用于产品内部结构相似、构建过程稳定的情况。
1.3 两种Go实现的对比与选择
建造者模式的核心价值在于分离复杂对象的构建过程和它的表示。
 在Go语言中,我们有两种主要的实现方式:
- 经典建造者模式:结构严谨,适合构建流程复杂且固定的场景。
- 函数式选项模式:Go语言中的惯用模式,通过可变参数和闭包,以更简洁、灵活的方式实现了建造者的核心思想,是处理可选参数和多参数构造问题的首选方案。
| 特性 | 经典建造者模式 | 函数式选项模式 | 
|---|---|---|
| 结构 | 角色分明(Director, Builder, Product),结构更“重”。 | 结构轻量,主要由 Option函数和构造函数组成。 | 
| 灵活性 | Director提供了固定的构建流程,但客户端也可直接使用Builder,灵活性高。 | 极其灵活,客户端可以任意组合选项函数。 | 
| 代码量 | 较多,需要定义多个接口和结构体。 | 较少,通常只需定义产品、 Option类型和一系列WithXxx函数。 | 
| 可读性 | 构建过程被封装在 Director中,对于复杂流程可能更清晰。 | 构造函数调用处非常直观,一目了然地看到了所有配置。 | 
| Go风格 | 更偏向于经典的面向对象设计,在Go中略显笨重。 | 非常符合Go的哲学,简洁、优雅、可组合,是Go社区处理多参数构造问题的事实标准。 | 
| 适用场景 | 当构建过程非常复杂,有严格的、固定的多步骤顺序时,经典模式更合适。 | 绝大多数场景,特别是当构造函数参数多、有默认值、部分参数可选时。 | 
如何选择?
- 优先选择函数式选项模式。在99%的Go开发场景中,它都是更优的选择。它完美解决了构造函数参数过多的问题,同时保持了代码的简洁和可扩展性。
- 只有当你的对象构建逻辑极其复杂,包含多个有严格顺序依赖的步骤,并且你希望将这些步骤**封装成一个可复用的“算法”**时,才考虑使用经典的建造者模式。例如,构建一个复杂的SQL查询、一个PDF文档或者一个网络请求的配置流。
二、案例:实现「手机(Phone)」的建造者模式
假设我们需要构建不同配置的手机,包含 品牌、CPU、内存、摄像头、系统 等部件,用户可能需要「入门机」「旗舰机」等不同类型。使用建造者模式可灵活组装这些部件,同时保证构建流程的一致性。
1.1 定义产品结构体(Phone)
首先定义最终要创建的复杂对象——手机,包含基本属性和展示信息的方法。
package mainimport "fmt"// Phone 产品类:手机
type Phone struct {Brand    string // 品牌CPU      string // 处理器Memory   string // 内存Camera   string // 摄像头System   string // 系统Battery  string // 电池
}// ShowInfo 展示手机配置
func (p *Phone) ShowInfo() {fmt.Printf("手机配置:\n")fmt.Printf("品牌:%s\n", p.Brand)fmt.Printf("CPU:%s\n", p.CPU)fmt.Printf("内存:%s\n", p.Memory)fmt.Printf("摄像头:%s\n", p.Camera)fmt.Printf("系统:%s\n", p.System)fmt.Printf("电池:%s\n", p.Battery)
}
1.2 定义建造者接口(PhoneBuilder)
在 Go 中通过接口定义建造者的「构建步骤」,具体建造者需实现这些方法。
// PhoneBuilder 建造者接口:定义构建手机的步骤
type PhoneBuilder interface {SetBrand()    // 设置品牌SetCPU()      // 设置CPUSetMemory()   // 设置内存SetCamera()   // 设置摄像头SetSystem()   // 设置系统SetBattery()  // 设置电池GetPhone() *Phone // 返回构建好的手机
}
1.3 实现具体建造者
根据不同需求实现具体建造者(如「入门机建造者」「旗舰机建造者」),每个建造者负责具体的部件配置。
// EntryLevelPhoneBuilder 具体建造者:入门级手机
type EntryLevelPhoneBuilder struct {phone *Phone // 持有一个手机对象
}// 初始化建造者
func NewEntryLevelPhoneBuilder() *EntryLevelPhoneBuilder {return &EntryLevelPhoneBuilder{phone: &Phone{},}
}func (e *EntryLevelPhoneBuilder) SetBrand() {e.phone.Brand = "红米"
}func (e *EntryLevelPhoneBuilder) SetCPU() {e.phone.CPU = "骁龙695"
}func (e *EntryLevelPhoneBuilder) SetMemory() {e.phone.Memory = "6GB + 128GB"
}func (e *EntryLevelPhoneBuilder) SetCamera() {e.phone.Camera = "4800万像素单摄"
}func (e *EntryLevelPhoneBuilder) SetSystem() {e.phone.System = "MIUI 15"
}func (e *EntryLevelPhoneBuilder) SetBattery() {e.phone.Battery = "5000mAh"
}func (e *EntryLevelPhoneBuilder) GetPhone() *Phone {return e.phone
}// FlagshipPhoneBuilder 具体建造者:旗舰级手机
type FlagshipPhoneBuilder struct {phone *Phone
}func NewFlagshipPhoneBuilder() *FlagshipPhoneBuilder {return &FlagshipPhoneBuilder{phone: &Phone{},}
}func (f *FlagshipPhoneBuilder) SetBrand() {f.phone.Brand = "小米"
}func (f *FlagshipPhoneBuilder) SetCPU() {f.phone.CPU = "骁龙8 Gen3"
}func (f *FlagshipPhoneBuilder) SetMemory() {f.phone.Memory = "12GB + 512GB"
}func (f *FlagshipPhoneBuilder) SetCamera() {f.phone.Camera = "1亿像素三摄(OIS光学防抖)"
}func (f *FlagshipPhoneBuilder) SetSystem() {f.phone.System = "MIUI 15(基于Android 14)"
}func (f *FlagshipPhoneBuilder) SetBattery() {f.phone.Battery = "5500mAh(120W快充)"
}func (f *FlagshipPhoneBuilder) GetPhone() *Phone {return f.phone
}
1.4 定义指挥者(Director)
指挥者负责控制构建流程,按固定步骤调用建造者的方法,确保构建过程的一致性(无需关心具体部件细节)。
// Director 指挥者:控制构建流程
type Director struct {builder PhoneBuilder // 持有一个建造者接口
}// 初始化指挥者
func NewDirector(builder PhoneBuilder) *Director {return &Director{builder: builder,}
}// Construct 按固定步骤构建手机
func (d *Director) Construct() {d.builder.SetBrand()d.builder.SetCPU()d.builder.SetMemory()d.builder.SetCamera()d.builder.SetSystem()d.builder.SetBattery()
}
1.5 客户端调用
客户端只需选择具体的建造者,通过指挥者完成构建,无需关心内部细节。
func main() {// 构建入门级手机entryBuilder := NewEntryLevelPhoneBuilder()entryDirector := NewDirector(entryBuilder)entryDirector.Construct() // 执行构建流程entryPhone := entryBuilder.GetPhone()fmt.Println("=== 入门级手机 ===")entryPhone.ShowInfo()// 构建旗舰级手机flagshipBuilder := NewFlagshipPhoneBuilder()flagshipDirector := NewDirector(flagshipBuilder)flagshipDirector.Construct()flagshipPhone := flagshipBuilder.GetPhone()fmt.Println("\n=== 旗舰级手机 ===")flagshipPhone.ShowInfo()
}
1.6 完整代码与执行结果
完整代码(builder_pattern.go)
package mainimport "fmt"// Phone 产品类:手机
type Phone struct {Brand   string // 品牌CPU     string // 处理器Memory  string // 内存Camera  string // 摄像头System  string // 系统Battery string // 电池
}// ShowInfo 展示手机配置
func (p *Phone) ShowInfo() {fmt.Printf("手机配置:\n")fmt.Printf("品牌:%s\n", p.Brand)fmt.Printf("CPU:%s\n", p.CPU)fmt.Printf("内存:%s\n", p.Memory)fmt.Printf("摄像头:%s\n", p.Camera)fmt.Printf("系统:%s\n", p.System)fmt.Printf("电池:%s\n", p.Battery)
}// PhoneBuilder 建造者接口:定义构建手机的步骤
type PhoneBuilder interface {SetBrand()   // 设置品牌SetCPU()     // 设置CPUSetMemory()  // 设置内存SetCamera()  // 设置摄像头SetSystem()  // 设置系统SetBattery() // 设置电池GetPhone() *Phone
}// EntryLevelPhoneBuilder 具体建造者:入门级手机
type EntryLevelPhoneBuilder struct {phone *Phone
}func NewEntryLevelPhoneBuilder() *EntryLevelPhoneBuilder {return &EntryLevelPhoneBuilder{phone: &Phone{},}
}func (e *EntryLevelPhoneBuilder) SetBrand() {e.phone.Brand = "红米"
}func (e *EntryLevelPhoneBuilder) SetCPU() {e.phone.CPU = "骁龙695"
}func (e *EntryLevelPhoneBuilder) SetMemory() {e.phone.Memory = "6GB + 128GB"
}func (e *EntryLevelPhoneBuilder) SetCamera() {e.phone.Camera = "4800万像素单摄"
}func (e *EntryLevelPhoneBuilder) SetSystem() {e.phone.System = "MIUI 15"
}func (e *EntryLevelPhoneBuilder) SetBattery() {e.phone.Battery = "5000mAh"
}func (e *EntryLevelPhoneBuilder) GetPhone() *Phone {return e.phone
}// FlagshipPhoneBuilder 具体建造者:旗舰级手机
type FlagshipPhoneBuilder struct {phone *Phone
}func NewFlagshipPhoneBuilder() *FlagshipPhoneBuilder {return &FlagshipPhoneBuilder{phone: &Phone{},}
}func (f *FlagshipPhoneBuilder) SetBrand() {f.phone.Brand = "小米"
}func (f *FlagshipPhoneBuilder) SetCPU() {f.phone.CPU = "骁龙8 Gen3"
}func (f *FlagshipPhoneBuilder) SetMemory() {f.phone.Memory = "12GB + 512GB"
}func (f *FlagshipPhoneBuilder) SetCamera() {f.phone.Camera = "1亿像素三摄(OIS光学防抖)"
}func (f *FlagshipPhoneBuilder) SetSystem() {f.phone.System = "MIUI 15(基于Android 14)"
}func (f *FlagshipPhoneBuilder) SetBattery() {f.phone.Battery = "5500mAh(120W快充)"
}func (f *FlagshipPhoneBuilder) GetPhone() *Phone {return f.phone
}// Director 指挥者:控制构建流程
type Director struct {builder PhoneBuilder
}func NewDirector(builder PhoneBuilder) *Director {return &Director{builder: builder,}
}func (d *Director) Construct() {d.builder.SetBrand()d.builder.SetCPU()d.builder.SetMemory()d.builder.SetCamera()d.builder.SetSystem()d.builder.SetBattery()
}func main() {// 构建入门级手机entryBuilder := NewEntryLevelPhoneBuilder()entryDirector := NewDirector(entryBuilder)entryDirector.Construct()entryPhone := entryBuilder.GetPhone()fmt.Println("=== 入门级手机 ===")entryPhone.ShowInfo()// 构建旗舰级手机flagshipBuilder := NewFlagshipPhoneBuilder()flagshipDirector := NewDirector(flagshipBuilder)flagshipDirector.Construct()flagshipPhone := flagshipBuilder.GetPhone()fmt.Println("\n=== 旗舰级手机 ===")flagshipPhone.ShowInfo()
}
执行结果
# 运行命令
go run builder_pattern.go# 输出
=== 入门级手机 ===
手机配置:
品牌:红米
CPU:骁龙695
内存:6GB + 128GB
摄像头:4800万像素单摄
系统:MIUI 15
电池:5000mAh=== 旗舰级手机 ===
手机配置:
品牌:小米
CPU:骁龙8 Gen3
内存:12GB + 512GB
摄像头:1亿像素三摄(OIS光学防抖)
系统:MIUI 15(基于Android 14)
电池:5500mAh(120W快充)
三、Go风格建造者模式
函数式选项模式(Functional Options)
package mainimport "fmt"// Computer 使用函数式选项模式
type Computer struct {CPU     stringMemory  stringStorage stringGPU     stringMonitor stringNetwork string
}// ComputerOption 选项函数类型
type ComputerOption func(*Computer)// 选项函数
func WithCPU(cpu string) ComputerOption {return func(c *Computer) {c.CPU = cpu}
}func WithMemory(memory string) ComputerOption {return func(c *Computer) {c.Memory = memory}
}func WithStorage(storage string) ComputerOption {return func(c *Computer) {c.Storage = storage}
}func WithGPU(gpu string) ComputerOption {return func(c *Computer) {c.GPU = gpu}
}func WithMonitor(monitor string) ComputerOption {return func(c *Computer) {c.Monitor = monitor}
}func WithNetwork(network string) ComputerOption {return func(c *Computer) {c.Network = network}
}// NewComputer 构造函数
func NewComputer(opts ...ComputerOption) *Computer {computer := &Computer{// 默认值CPU:     "Intel i5",Memory:  "8GB",Storage: "256GB SSD",Network: "1G Ethernet",}for _, opt := range opts {opt(computer)}return computer
}func (c *Computer) Show() {fmt.Printf("电脑配置:\n")fmt.Printf("  CPU: %s\n", c.CPU)fmt.Printf("  内存: %s\n", c.Memory)fmt.Printf("  存储: %s\n", c.Storage)fmt.Printf("  网络: %s\n", c.Network)if c.GPU != "" {fmt.Printf("  显卡: %s\n", c.GPU)}if c.Monitor != "" {fmt.Printf("  显示器: %s\n", c.Monitor)}fmt.Println()
}// 使用示例
func functionalOptionsExample() {fmt.Println("=== 函数式选项模式示例 ===")// 默认配置defaultPC := NewComputer()defaultPC.Show()// 游戏配置gamingPC := NewComputer(WithCPU("Intel i9-13900K"),WithMemory("32GB DDR5"),WithStorage("2TB NVMe SSD"),WithGPU("NVIDIA RTX 4090"),WithMonitor("27寸 4K 144Hz"),WithNetwork("2.5G Ethernet"),)gamingPC.Show()// 服务器配置serverPC := NewComputer(WithCPU("AMD EPYC 7713"),WithMemory("128GB DDR4 ECC"),WithStorage("4TB NVMe SSD"),WithNetwork("10G Ethernet"),)serverPC.Show()
}func main() {functionalOptionsExample()
}
执行结果如下:
=== 函数式选项模式示例 ===
电脑配置:CPU: Intel i5内存: 8GB存储: 256GB SSD网络: 1G Ethernet电脑配置:CPU: Intel i9-13900K内存: 32GB DDR5存储: 2TB NVMe SSD网络: 2.5G Ethernet显卡: NVIDIA RTX 4090显示器: 27寸 4K 144Hz电脑配置:CPU: AMD EPYC 7713内存: 128GB DDR4 ECC存储: 4TB NVMe SSD网络: 10G Ethernet