深入解析:Go语言设计模式:建造者模式详解

news/2025/11/28 14:04:56/文章来源:https://www.cnblogs.com/gccbuaa/p/19282381

文章目录

    • 一、建造者模式概述
      • 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社区处理多参数构造问题的事实标准
适用场景当构建过程非常复杂,有严格的、固定的多步骤顺序时,经典模式更合适。绝大多数场景,特别是当构造函数参数多、有默认值、部分参数可选时。

如何选择?

二、案例:实现「手机(Phone)」的建造者模式

假设我们需要构建不同配置的手机,包含 品牌、CPU、内存、摄像头、系统 等部件,用户可能需要「入门机」「旗舰机」等不同类型。使用建造者模式可灵活组装这些部件,同时保证构建流程的一致性。

1.1 定义产品结构体(Phone)

首先定义最终要创建的复杂对象——手机,包含基本属性和展示信息的方法。

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 中通过接口定义建造者的「构建步骤」,具体建造者需实现这些方法。

// PhoneBuilder 建造者接口:定义构建手机的步骤
type PhoneBuilder interface {
SetBrand()    // 设置品牌
SetCPU()      // 设置CPU
SetMemory()   // 设置内存
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 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()
}

执行结果

# 运行命令
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 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()
}

执行结果如下:

=== 函数式选项模式示例 ===
电脑配置:
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.mzph.cn/news/979714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025年市面上有名的ISO认证公司哪家强,ISO27018认证/ISO27040认证/CS认证/CCRC认证申请选哪家

行业背景分析 随着深圳企业对国际标准化认证需求的持续增长,ISO认证咨询行业迎来了新一轮发展机遇。作为改革开放的前沿阵地,深圳企业对于质量管理体系、环境管理体系等国际标准认证的需求日益提升,专业的ISO认证咨…

ReentrantReadWriteLock 和 ReentrantLock 的联系与区别

相同点可重入性两者都支持可重入,同一线程可以多次获取相同的锁 都维护着获取锁的次数计数器公平性策略都支持公平锁和非公平锁模式 构造函数都可以指定是否采用公平策略底层实现都基于 AbstractQueuedSynchronizer(A…

2025 年 11 月企业咨询公司权威推荐榜:战略规划、组织优化与数字化转型顶尖服务商深度解析

2025 年 11 月企业咨询公司权威推荐榜:战略规划、组织优化与数字化转型顶尖服务商深度解析 在当今快速变化的商业环境中,企业咨询公司正发挥着越来越重要的作用。随着数字化转型浪潮的持续推进,以及企业在战略规划和…

2025年高压潜水轴流泵直销厂家权威推荐榜单:污水潜水泵/雪橇式轴流泵/卧式潜水泵源头厂家精选

在水利工程、城市给排水与农田灌溉领域,高压潜水轴流泵作为关键排水与输水设备,其性能优劣直接影响到整个系统的运行效率与可靠性。根据水务行业数据显示,我国水泵市场规模预计在2025年将达到约1500亿元,年增长率稳…

贝赛思速提分攻略!2025贝赛思备考机构TOP5,无老师领衔,提分率超90%

贝赛思速提分攻略!2025贝赛思备考机构TOP5,无老师领衔,提分率超90%备战贝赛思国际学校时,其独特的MAP考试体系、全英文授课要求及严格的学术评估标准,让众多家长和学员在选择备考机构时倍感困惑。我们通过调研近百…

微算法科技(NASDAQ:MLGO)深度学习区块链技术:构建信任+智能双引擎的数字新生态

在数字化浪潮席卷全球的背景下,区块链技术凭借去中心化架构与不可篡改特性,为数字世界构建了坚实的信任基石。然而,其静态数据存储模式与有限的处理能力,使得在复杂场景下的深度分析与智能决策存在天然短板。与此同…

USB 2.0 高速 低速协商过程

设备先上拉 D+,触发主机识别USB 全速和高速设备的硬件设计中,D + 引脚都会接 1.5K 上拉电阻。当设备接入 USB 总线后,Hub 的 D+/D - 引脚原本因 15K 下拉电阻处于低电平,设备 D + 的上拉电阻会使 Hub 对应引脚电平…

rust语言下划线_作用有哪些

在 Rust 语言中,下划线 _ 是一个非常有用的特殊符号,它具有多种不同的含义和用途,但核心思想通常是表示“占位符”或“忽略”。 以下是 _ 的几种主要用法: 1. 用作通配符(占位符) 这是 _ 最常见的用法。它用于模…

2025年十大农产品冷库安装公司排行榜,冷库安装专业制造商新

为帮助企业在冷库安装市场中精准锁定适配自身需求的合作伙伴,避免陷入低价劣质陷阱,我们从技术落地能力(如全温域覆盖、节能改造技术)、服务保障体系(含全流程质控、售后响应速度)、真实客户口碑(侧重同行业项目…

抓VSS坐标脚本

set net VSS set point_type "down" set gnd_i 0 redirect ../scr/$net.loc {} redirect ../scr/$net.loc {foreach shape [dbGet selected.net.name $net -p2] {set llx [dbGet $shape.box_llx]set lly [db…

2025 年 11 月企业管理咨询公司权威推荐榜:战略赋能与组织变革的行业影响力深度解析

2025 年 11 月企业管理咨询公司权威推荐榜:战略赋能与组织变革的行业影响力深度解析 在当今快速变化的商业环境中,企业管理咨询公司正发挥着越来越重要的作用。随着数字化转型、全球化竞争加剧以及新兴商业模式的涌现…

fastapi python项目构建 路由设置

FastAPI 是一个现代、快速(高性能)的 Python Web 框架,专门用于构建 API。它结合了 Python 类型提示的强大功能和异步编程的支持。 核心特性 1. 高性能基于 Starlette(Web 框架)和 Pydantic(数据验证)性能可与 …

2025 年 11 月企业管理咨询公司十强权威推荐榜:战略规划与组织优化实力派首选,助力企业高效成长与持续领先

2025 年 11 月企业管理咨询公司十强权威推荐榜:战略规划与组织优化实力派首选,助力企业高效成长与持续领先 在全球经济格局深度调整的背景下,企业管理咨询行业正迎来新一轮发展机遇。随着数字化转型浪潮的推进和市场…

2025年川渝黔实用时尚西餐料理培训哪家好?十大靠谱机构推荐

TOP1 推荐:重庆欧米奇西点西餐学校 推荐指数:★★★★★ 口碑评分:川渝黔地区西餐培训品牌 专业能力:重庆欧米奇深耕西式饮食教育三十余年,依托新华教育集团上市品牌资源,构建技能+学历+就业三位一体教学体系。以…

ReentrantLock 的典型使用场景和实现方法

基本概念 ReentrantLock 是 Java 幑发包中提供的可重入互斥锁,相比 synchronized 关键字提供了更高的灵活性和功能。 典型使用场景 1. 防止重复提交 防止用户重复点击按钮导致的重复业务处理。 2. 缓存双检锁机制 在缓…

2025 年 11 月制造业降本增效咨询公司权威推荐榜:精益生产与成本优化专家团队深度解析及服务优势全景解析

2025年11月制造业降本增效咨询公司权威推荐榜:精益生产与成本优化专家团队深度解析及服务优势全景解析 引言:制造业降本增效的时代背景 在全球制造业竞争日趋激烈的今天,降本增效已成为制造企业生存与发展的核心命题…

无源探头与高压探头技术对比分析

本文对比分析了无源探头与高压探头的技术原理、性能参数及应用场景,为选择合适探头提供参考。在电子测量领域,示波器探头作为连接被测电路与测量仪器的桥梁,其性能直接影响测量结果的准确性。其中,无源探头和高压探…

数字马力笔试

选择题七八十道的样子,包含 AI、Java 面向对象、数据库等。 编程题五道: 一五是算法,第一题是模拟,给你个身份证,问最后一位和前面 \(9\) 位算出的一个结果是否匹配,我记得好像是牛客上的原题。 第五题是给你两个…

2025年上海离婚诉讼律师推荐排行榜,哪个好?哪个靠谱?选哪个?

在上海提起离婚诉讼,选对“上海离婚诉讼律师”基本等于赢了一半:不仅关系到能不能顺利离掉,还关系到房子、存款、股权、孩子抚养权这些“人生核心资源”怎么分配。 网上各种“排行榜”“十大离婚律师”里,广告、水…

直击提分痛点!2025年11月贝赛思考试培训核心机构深度评测,封闭班首选推荐

直击提分痛点!2025年11月贝赛思考试培训核心机构深度评测,封闭班首选推荐备考贝赛思考试时,面对市场上良莠不齐的培训机构,不少家长和学员都陷入选择困境。2025年贝赛思考试难度再升级,MAP阅读题量翻倍至40题,数…