在软件开发中,创建复杂对象往往需要经历多个步骤,且不同场景下对象的组件配置、构建顺序可能存在差异。建造者模式(Builder Pattern)作为经典的创建型设计模式,核心价值在于将复杂对象的构建过程与最终表示分离,让相同的构建流程能生成不同的产品形态,同时屏蔽底层构建细节,大幅提升代码的灵活性与可维护性。
一、建造者模式核心结构
建造者模式通过分层设计解耦对象构建逻辑,其经典结构包含5个核心角色,各角色分工明确、协同完成复杂对象的创建,确保构建过程的规范性与灵活性。
1.1 核心角色及职责
| 角色 |
核心职责 |
| 产品(Product) |
待构建的复杂对象,由多个组件/部分组成(如电脑包含CPU、内存、硬盘等核心组件)。 |
| 抽象建造者(Builder) |
定义构建产品各组件的抽象接口,声明“构建组件”和“获取产品”的核心方法,为所有具体建造者提供统一规范。 |
| 具体建造者(ConcreteBuilder) |
实现抽象建造者的接口,完成产品各组件的具体构建逻辑,内部持有最终构建的产品实例,负责组件的组装与初始化。 |
| 指挥者(Director) |
控制构建流程的执行顺序,调用具体建造者的方法完成对象构建,隔离客户端与底层构建细节,确保流程的一致性。 |
| 客户端(Client) |
创建指挥者和具体建造者实例,通过指挥者触发构建流程,无需关注构建细节,最终获取成品对象。 |
1.2 核心设计思想
建造者模式的核心逻辑的是“分离构建与表示”:客户端只需指定具体建造者的类型,指挥者便会按照预设流程调用建造者的组件构建方法,无需关注组件如何组装、顺序如何安排,即可生成不同配置的产品。这种设计既保证了构建流程的规范性,又实现了产品变体的灵活扩展。
二、多语言实现建造者模式
为便于跨语言对比理解,本文以“构建不同配置的电脑”为统一场景(产品:电脑;具体建造者:游戏电脑建造者、办公电脑建造者;指挥者:电脑组装指挥者),分别通过C#、Python、Golang、C++、纯C语言实现建造者模式,贴合各语言特性与工程实践规范,所有代码均可直接编译运行。
2.1 C# 实现(抽象类+继承,经典面向对象落地)
C#作为强类型面向对象语言,完全契合建造者模式的经典类结构,通过抽象类定义建造规范,子类实现具体构建逻辑,具备良好的类型安全性和代码可读性,适合企业级系统开发。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| using System;
public class Computer { public string CPU { get; set; } public string RAM { get; set; } public string HardDisk { get; set; }
public override string ToString() { return $"电脑配置:CPU={CPU},内存={RAM},硬盘={HardDisk}"; } }
public abstract class ComputerBuilder { protected Computer _computer = new Computer(); public abstract void BuildCPU(); public abstract void BuildRAM(); public abstract void BuildHardDisk(); public Computer GetComputer() => _computer; }
public class GamingComputerBuilder : ComputerBuilder { public override void BuildCPU() => _computer.CPU = "Intel i9-14900K"; public override void BuildRAM() => _computer.RAM = "32GB DDR5 6400"; public override void BuildHardDisk() => _computer.HardDisk = "2TB NVMe PCIe4.0"; }
public class OfficeComputerBuilder : ComputerBuilder { public override void BuildCPU() => _computer.CPU = "Intel i5-13400"; public override void BuildRAM() => _computer.RAM = "16GB DDR4 3200"; public override void BuildHardDisk() => _computer.HardDisk = "1TB SATA3 SSD"; }
public class ComputerDirector { public Computer Construct(ComputerBuilder builder) { builder.BuildCPU(); builder.BuildRAM(); builder.BuildHardDisk(); return builder.GetComputer(); } }
class Program { static void Main(string[] args) { ComputerDirector director = new ComputerDirector(); ComputerBuilder gamingBuilder = new GamingComputerBuilder(); Computer gamingPC = director.Construct(gamingBuilder); Console.WriteLine(gamingPC);
ComputerBuilder officeBuilder = new OfficeComputerBuilder(); Computer officePC = director.Construct(officeBuilder); Console.WriteLine(officePC); } }
|
2.2 Python 实现(动态特性+极简设计)
Python无严格的抽象类语法,通过基类抛出异常实现“抽象接口”的约束,结合动态语言的灵活性简化代码,无需繁琐的类型声明,兼顾可读性与开发效率,适合快速迭代场景。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| class Computer: def __init__(self): self.cpu = None self.ram = None self.hard_disk = None
def __str__(self): return f"电脑配置:CPU={self.cpu},内存={self.ram},硬盘={self.hard_disk}"
class ComputerBuilder: def __init__(self): self.computer = Computer()
def build_cpu(self): raise NotImplementedError("子类必须重写build_cpu方法,实现CPU构建逻辑")
def build_ram(self): raise NotImplementedError("子类必须重写build_ram方法,实现内存构建逻辑")
def build_hard_disk(self): raise NotImplementedError("子类必须重写build_hard_disk方法,实现硬盘构建逻辑")
def get_computer(self): return self.computer
class GamingComputerBuilder(ComputerBuilder): def build_cpu(self): self.computer.cpu = "AMD Ryzen 9 7950X"
def build_ram(self): self.computer.ram = "64GB DDR5 6000"
def build_hard_disk(self): self.computer.hard_disk = "4TB NVMe PCIe5.0"
class OfficeComputerBuilder(ComputerBuilder): def build_cpu(self): self.computer.cpu = "AMD Ryzen 5 7600"
def build_ram(self): self.computer.ram = "8GB DDR4 3200"
def build_hard_disk(self): self.computer.hard_disk = "512GB SATA3 SSD"
class ComputerDirector: @staticmethod def construct(builder): builder.build_cpu() builder.build_ram() builder.build_hard_disk() return builder.get_computer()
if __name__ == "__main__": gaming_builder = GamingComputerBuilder() gaming_pc = ComputerDirector.construct(gaming_builder) print(gaming_pc)
office_builder = OfficeComputerBuilder() office_pc = ComputerDirector.construct(office_builder) print(office_pc)
|
2.3 Golang 实现(接口+结构体,面向接口编程)
Golang无类和继承特性,核心是“面向接口编程”,通过接口定义建造者规范,结构体实现接口方法,贴合Go语言“极简、高效”的设计哲学,代码无冗余、执行效率高。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| package main
import "fmt"
type Computer struct { CPU string RAM string HardDisk string }
func (c *Computer) String() string { return fmt.Sprintf("电脑配置:CPU=%s,内存=%s,硬盘=%s", c.CPU, c.RAM, c.HardDisk) }
type ComputerBuilder interface { BuildCPU() BuildRAM() BuildHardDisk() GetComputer() *Computer }
type GamingComputerBuilder struct { computer *Computer }
func NewGamingComputerBuilder() *GamingComputerBuilder { return &GamingComputerBuilder{computer: &Computer{}} }
func (g *GamingComputerBuilder) BuildCPU() { g.computer.CPU = "Intel i7-14700KF" }
func (g *GamingComputerBuilder) BuildRAM() { g.computer.RAM = "48GB DDR5 6200" }
func (g *GamingComputerBuilder) BuildHardDisk() { g.computer.HardDisk = "2TB NVMe PCIe4.0" }
func (g *GamingComputerBuilder) GetComputer() *Computer { return g.computer }
type OfficeComputerBuilder struct { computer *Computer }
func NewOfficeComputerBuilder() *OfficeComputerBuilder { return &OfficeComputerBuilder{computer: &Computer{}} }
func (o *OfficeComputerBuilder) BuildCPU() { o.computer.CPU = "Intel i3-12100" }
func (o *OfficeComputerBuilder) BuildRAM() { o.computer.RAM = "8GB DDR4 2666" }
func (o *OfficeComputerBuilder) BuildHardDisk() { o.computer.HardDisk = "512GB SATA3 SSD" }
func (o *OfficeComputerBuilder) GetComputer() *Computer { return o.computer }
type ComputerDirector struct{}
func (d *ComputerDirector) Construct(builder ComputerBuilder) *Computer { builder.BuildCPU() builder.BuildRAM() builder.BuildHardDisk() return builder.GetComputer() }
func main() { director := &ComputerDirector{} gamingBuilder := NewGamingComputerBuilder() gamingPC := director.Construct(gamingBuilder) fmt.Println(gamingPC)
officeBuilder := NewOfficeComputerBuilder() officePC := director.Construct(officeBuilder) fmt.Println(officePC) }
|
2.4 C++ 实现(抽象类+多态,高性能落地)
C++通过纯虚函数定义抽象建造者接口,子类继承并实现具体构建逻辑,需注意定义虚析构函数以避免内存泄漏,兼顾多态特性与性能,适合高性能、底层开发场景,是建造者模式的经典落地方式。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| #include <iostream> #include <string> using namespace std;
class Computer { private: string cpu; string ram; string hardDisk; public: void setCPU(string cpu) { this->cpu = cpu; } void setRAM(string ram) { this->ram = ram; } void setHardDisk(string hardDisk) { this->hardDisk = hardDisk; } string toString() { return "电脑配置:CPU=" + cpu + ",内存=" + ram + ",硬盘=" + hardDisk; } };
class ComputerBuilder { protected: Computer* computer; public: ComputerBuilder() { computer = new Computer(); } virtual ~ComputerBuilder() { delete computer; } virtual void buildCPU() = 0; virtual void buildRAM() = 0; virtual void buildHardDisk() = 0; Computer* getComputer() { return computer; } };
class GamingComputerBuilder : public ComputerBuilder { public: void buildCPU() override { computer->setCPU("AMD Ryzen 7 7800X3D"); } void buildRAM() override { computer->setRAM("32GB DDR5 5600"); } void buildHardDisk() override { computer->setHardDisk("2TB NVMe PCIe4.0"); } };
class OfficeComputerBuilder : public ComputerBuilder { public: void buildCPU() override { computer->setCPU("AMD Ryzen 3 7300X"); } void buildRAM() override { computer->setRAM("16GB DDR4 3200"); } void buildHardDisk() override { computer->setHardDisk("1TB SATA3 HDD"); } };
class ComputerDirector { public: Computer* construct(ComputerBuilder* builder) { builder->buildCPU(); builder->buildRAM(); builder->buildHardDisk(); return builder->getComputer(); } };
int main() { ComputerDirector director; ComputerBuilder* gamingBuilder = new GamingComputerBuilder(); Computer* gamingPC = director.construct(gamingBuilder); cout << gamingPC->toString() << endl;
ComputerBuilder* officeBuilder = new OfficeComputerBuilder(); Computer* officePC = director.construct(officeBuilder); cout << officePC->toString() << endl;
delete gamingBuilder; delete officeBuilder; delete gamingPC; delete officePC; return 0; }
|
2.5 纯C语言实现(结构体+函数指针,模拟面向对象)
纯C语言无面向对象特性,通过“结构体封装数据、函数指针封装行为”模拟抽象建造者和多态特性,核心是解耦构建流程与组件实现,代码轻量化、执行高效,适合嵌入式、底层开发场景。
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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
| #include <stdio.h> #include <stdlib.h> #include <string.h>
typedef struct { char cpu[32]; char ram[32]; char hard_disk[32]; } Computer;
typedef struct { Computer* computer; void (*build_cpu)(struct ComputerBuilder*); void (*build_ram)(struct ComputerBuilder*); void (*build_hard_disk)(struct ComputerBuilder*); } ComputerBuilder;
typedef struct { ComputerBuilder builder; } GamingComputerBuilder;
void gaming_build_cpu(ComputerBuilder* b) { strcpy(b->computer->cpu, "Intel i9-14900KF"); }
void gaming_build_ram(ComputerBuilder* b) { strcpy(b->computer->ram, "64GB DDR5 6400"); }
void gaming_build_hard_disk(ComputerBuilder* b) { strcpy(b->computer->hard_disk, "4TB NVMe PCIe5.0"); }
GamingComputerBuilder* new_gaming_builder() { GamingComputerBuilder* builder = (GamingComputerBuilder*)malloc(sizeof(GamingComputerBuilder)); builder->builder.computer = (Computer*)malloc(sizeof(Computer)); builder->builder.build_cpu = gaming_build_cpu; builder->builder.build_ram = gaming_build_ram; builder->builder.build_hard_disk = gaming_build_hard_disk; return builder; }
typedef struct { ComputerBuilder builder; } OfficeComputerBuilder;
void office_build_cpu(ComputerBuilder* b) { strcpy(b->computer->cpu, "Intel i5-12400"); }
void office_build_ram(ComputerBuilder* b) { strcpy(b->computer->ram, "16GB DDR4 3200"); }
void office_build_hard_disk(ComputerBuilder* b) { strcpy(b->computer->hard_disk, "1TB SATA3 SSD"); }
OfficeComputerBuilder* new_office_builder() { OfficeComputerBuilder* builder = (OfficeComputerBuilder*)malloc(sizeof(OfficeComputerBuilder)); builder->builder.computer = (Computer*)malloc(sizeof(Computer)); builder->builder.build_cpu = office_build_cpu; builder->builder.build_ram = office_build_ram; builder->builder.build_hard_disk = office_build_hard_disk; return builder; }
Computer* construct(ComputerBuilder* builder) { builder->build_cpu(builder); builder->build_ram(builder); builder->build_hard_disk(builder); return builder->computer; }
void print_computer(Computer* pc) { printf("电脑配置:CPU=%s,内存=%s,硬盘=%s\n", pc->cpu, pc->ram, pc->hard_disk); }
int main() { GamingComputerBuilder* gaming_builder = new_gaming_builder(); Computer* gaming_pc = construct(&gaming_builder->builder); print_computer(gaming_pc);
OfficeComputerBuilder* office_builder = new_office_builder(); Computer* office_pc = construct(&office_builder->builder); print_computer(office_pc);
free(gaming_builder->builder.computer); free(gaming_builder); free(office_builder->builder.computer); free(office_builder); free(gaming_pc); free(office_pc); return 0; }
|
三、建造者模式的优缺点
建造者模式是为解决复杂对象构建问题而生的,其优势与劣势均源于“分离构建与表示”的设计思路,需结合实际业务场景权衡使用。
3.1 核心优点
解耦构建与表示:产品的内部结构、组件组装逻辑封装在具体建造者中,产品结构变化时仅需修改建造者,无需改动指挥者和客户端,完全符合“开闭原则”。
灵活扩展产品变体:替换具体建造者即可快速生成不同配置的产品,无需修改构建流程,适配多变体产品的创建需求,降低扩展成本。
精细化控制构建过程:指挥者统一管理构建步骤,可实现分步构建、暂停/恢复构建,甚至动态调整组件配置,适用于需逐步组装的复杂对象。
提升代码可维护性:客户端无需关注复杂的构建细节,只需指定建造者类型,代码逻辑清晰、可读性强,便于后期迭代与调试。
3.2 主要缺点
适用场景受限:仅适用于“复杂对象+构建步骤固定”的场景,对于结构简单、无需分步构建的对象,使用建造者模式会增加代码冗余,降低开发效率。
类/结构体数量膨胀:每新增一种产品变体,需对应新增一个具体建造者,当产品变体过多时,会导致类/结构体数量激增,增加代码维护成本。
依赖固定构建流程:指挥者的构建顺序固定,若不同产品的构建顺序差异较大,需修改指挥者代码,违反“开闭原则”,灵活性不足。
四、建造者模式的使用场景
建造者模式的核心价值在于“复杂对象的分步构建与灵活扩展”,适用于以下核心场景,能显著提升代码的可维护性与扩展性:
复杂对象分步构建:对象由多个组件组成,且组件构建有明确顺序(如汽车组装:底盘→发动机→车身→内饰;文档生成:标题→正文→页码→格式)。
多变体产品创建:同一类产品有多种配置变体,且构建逻辑相似(如不同配置的电脑、不同规格的订单、不同样式的报表),需灵活切换产品形态。
屏蔽构建细节:希望客户端仅关注产品结果,无需了解组件如何组装、依赖如何处理(如框架中的对象工厂、SDK中的实例创建),降低客户端使用成本。
动态调整构建过程:需在构建过程中动态修改组件配置(如分步构建HTTP请求:先设置Header,再添加Body,最后设置请求参数)。
典型实战案例
JDK中的StringBuilder(简化版建造者,无指挥者,自身完成字符序列的分步构建);
MyBatis的SqlSessionFactoryBuilder(分步构建SqlSessionFactory,支持不同配置文件适配);
前端框架中复杂表单/组件的构建器(如Element UI的表单构建器,支持分步配置表单字段);
电商系统中的订单构建(不同类型订单的组件配置不同,通过建造者模式统一构建流程)。
五、总结
建造者模式的核心是“分离复杂对象的构建流程与组件实现”,通过抽象建造者定义规范、具体建造者实现细节、指挥者控制顺序,既解决了复杂对象构建的灵活性问题,又屏蔽了底层构建细节,提升了代码的可维护性与扩展性。
从多语言实现来看,尽管各语言的语法特性差异显著,但核心逻辑高度统一,均围绕“解耦构建与表示”展开:
使用建造者模式的关键是“匹配业务场景”:若对象结构简单、变体较少,无需使用建造者模式,避免过度设计;若对象复杂且需灵活定制、分步构建,建造者模式能发挥其最大价值。同时,无需拘泥于“指挥者+建造者”的固定结构,简化版建造者(无指挥者)在实际开发中也广泛应用,核心是把握“构建与表示分离”的本质,而非形式。