文章目录
-
- 一、建造者模式概述
-
- [1.1 建造者简介](#1.1 建造者简介)
- [1.2 建造者模式优缺点](#1.2 建造者模式优缺点)
- [1.3 两种Go实现的对比与选择](#1.3 两种Go实现的对比与选择)
- 二、案例:实现「手机(Phone)」的建造者模式
-
- [1.1 定义产品结构体(Phone)](#1.1 定义产品结构体(Phone))
- [1.2 定义建造者接口(PhoneBuilder)](#1.2 定义建造者接口(PhoneBuilder))
- [1.3 实现具体建造者](#1.3 实现具体建造者)
- [1.4 定义指挥者(Director)](#1.4 定义指挥者(Director))
- [1.5 客户端调用](#1.5 客户端调用)
- [1.6 完整代码与执行结果](#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)
首先定义最终要创建的复杂对象------手机,包含基本属性和展示信息的方法。
go
package main
import "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 中通过接口定义建造者的「构建步骤」,具体建造者需实现这些方法。
go
// PhoneBuilder 建造者接口:定义构建手机的步骤
type PhoneBuilder interface {
SetBrand() // 设置品牌
SetCPU() // 设置CPU
SetMemory() // 设置内存
SetCamera() // 设置摄像头
SetSystem() // 设置系统
SetBattery() // 设置电池
GetPhone() *Phone // 返回构建好的手机
}
1.3 实现具体建造者
根据不同需求实现具体建造者(如「入门机建造者」「旗舰机建造者」),每个建造者负责具体的部件配置。
go
// 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)
指挥者负责控制构建流程,按固定步骤调用建造者的方法,确保构建过程的一致性(无需关心具体部件细节)。
go
// 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 客户端调用
客户端只需选择具体的建造者,通过指挥者完成构建,无需关心内部细节。
go
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)
go
package main
import "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() // 设置CPU
SetMemory() // 设置内存
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()
}
执行结果
bash
# 运行命令
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)
go
package main
import "fmt"
// Computer 使用函数式选项模式
type Computer struct {
CPU string
Memory string
Storage string
GPU string
Monitor string
Network 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()
}
执行结果如下:
bash
=== 函数式选项模式示例 ===
电脑配置:
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