当前位置: 首页 > news >正文

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语言中,我们有两种主要的实现方式:

  1. 经典建造者模式:结构严谨,适合构建流程复杂且固定的场景。
  2. 函数式选项模式: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
http://www.dtcms.com/a/545103.html

相关文章:

  • 外观模式:复杂系统的统一入口
  • 个人做网站模版是否有人买如何引用网站图片
  • 库卡机器人通讯-EtherKRL-XML格式
  • 自动驾驶技术全景解析:从感知、决策到控制的演进与挑战
  • 建站平台在线提交表格apache 配置网站
  • 前端HTTP,JavaScript,网络
  • 汽车充电站光储充项目方案
  • 为什么Service层和Mapper层需要实现interface接口
  • 杭州做网站公司排名建筑工人招工网
  • 服务RejectedExecutionException问题对Semaphore的思考
  • GitLab 钩子 + Jenkins 自动化构建项目
  • 安装Pytorch GPU+CPU版本【通过本地安装解决无法使用pip指令下载问题】
  • DevExpress WinForms中文教程:Data Grid - 如何自定义汇总函数?
  • 西安建设市场诚信信息平台网站wordpress文章缩略图
  • 解锁未来:云原生如何重塑企业数字竞争力
  • 铜陵市建设工程管理局网站专业的网站开发团队
  • AI赋能座舱产品需求开发
  • SENT协议详解
  • 2026年ESWA SCI1区TOP,基于成本差异的跨境公路物流混合车队构成与调度:一种双层规划方法,深度解析+性能实测
  • 2025广州国际物联网产业生态博览会(物联网展)最新技术与亮点揭秘!
  • 【C++】哈希表实现 - 链地址法/哈希桶
  • 建设一个教程视频网站需要什么资质龙岗网络推广公司
  • 后端日志框架
  • 服务器在企业中的作用与价值
  • 《搭建属于自己的网站之网页前端学习》基础入门
  • 拿网站做商标童装网站建设
  • 金融投资网站毕设做网站是不是太low
  • 【pandas】pandas apply 方法详解
  • 散户如何运用券商手机智能T0算法
  • CRMEB-PHP订单删除机制详解