建造者模式

在软件开发中,创建复杂对象往往需要经历多个步骤,且不同场景下对象的组件配置、构建顺序可能存在差异。建造者模式(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; }

// 重写ToString,便于展示产品配置
public override string ToString()
{
return $"电脑配置:CPU={CPU},内存={RAM},硬盘={HardDisk}";
}
}

// 抽象建造者:定义电脑构建的统一接口
public abstract class ComputerBuilder
{
protected Computer _computer = new Computer(); // 持有产品实例,供子类操作
public abstract void BuildCPU(); // 构建CPU组件
public abstract void BuildRAM(); // 构建内存组件
public abstract void BuildHardDisk(); // 构建硬盘组件
public Computer GetComputer() => _computer; // 返回构建完成的产品
}

// 具体建造者1:游戏电脑建造者(高性能配置)
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";
}

// 具体建造者2:办公电脑建造者(高性价比配置)
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(); // 优先构建核心CPU
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 # CPU组件
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

# 具体建造者1:游戏电脑建造者
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"

# 具体建造者2:办公电脑建造者
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 // 硬盘
}

// 自定义String方法,用于展示产品配置
func (c *Computer) String() string {
return fmt.Sprintf("电脑配置:CPU=%s,内存=%s,硬盘=%s", c.CPU, c.RAM, c.HardDisk)
}

// 抽象建造者:接口定义电脑构建的规范
type ComputerBuilder interface {
BuildCPU() // 构建CPU
BuildRAM() // 构建内存
BuildHardDisk() // 构建硬盘
GetComputer() *Computer // 获取成品电脑
}

// 具体建造者1:游戏电脑建造者
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
}

// 具体建造者2:办公电脑建造者
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; // CPU组件
string ram; // 内存组件
string hardDisk; // 硬盘组件
public:
// 设置组件的setter方法
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; } // 返回成品
};

// 具体建造者1:游戏电脑建造者
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"); }
};

// 具体建造者2:办公电脑建造者
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]; // CPU组件
char ram[32]; // 内存组件
char hard_disk[32];// 硬盘组件
} Computer;

// 抽象建造者:函数指针模拟构建行为,定义统一规范
typedef struct {
Computer* computer;
void (*build_cpu)(struct ComputerBuilder*); // 构建CPU的函数指针
void (*build_ram)(struct ComputerBuilder*); // 构建内存的函数指针
void (*build_hard_disk)(struct ComputerBuilder*); // 构建硬盘的函数指针
} ComputerBuilder;

// 具体建造者1:游戏电脑建造者(组合抽象建造者,模拟继承)
typedef struct {
ComputerBuilder builder;
} GamingComputerBuilder;

// 游戏电脑CPU构建逻辑
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;
}

// 具体建造者2:办公电脑建造者(组合抽象建造者,模拟继承)
typedef struct {
ComputerBuilder builder;
} OfficeComputerBuilder;

// 办公电脑CPU构建逻辑
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的表单构建器,支持分步配置表单字段);

  • 电商系统中的订单构建(不同类型订单的组件配置不同,通过建造者模式统一构建流程)。

五、总结

建造者模式的核心是“分离复杂对象的构建流程与组件实现”,通过抽象建造者定义规范、具体建造者实现细节、指挥者控制顺序,既解决了复杂对象构建的灵活性问题,又屏蔽了底层构建细节,提升了代码的可维护性与扩展性。

从多语言实现来看,尽管各语言的语法特性差异显著,但核心逻辑高度统一,均围绕“解耦构建与表示”展开:

  • 面向对象语言(C#、Python、Golang、C++):通过类/接口/结构体+多态实现,贴合经典设计模式结构,代码更易理解与扩展,适配中高层开发场景;

  • 过程式语言(纯C):通过结构体+函数指针模拟面向对象特性,核心是封装构建行为,代码轻量化、执行高效,适配嵌入式、底层开发场景。

使用建造者模式的关键是“匹配业务场景”:若对象结构简单、变体较少,无需使用建造者模式,避免过度设计;若对象复杂且需灵活定制、分步构建,建造者模式能发挥其最大价值。同时,无需拘泥于“指挥者+建造者”的固定结构,简化版建造者(无指挥者)在实际开发中也广泛应用,核心是把握“构建与表示分离”的本质,而非形式。