建造者模式(Builder Pattern)的核心是将复杂对象的构建过程与表示分离 ,通过分步设置属性来创建对象,适合构建具有多个可选参数或复杂初始化逻辑的对象。在C语言中,可以通过结构体(表示对象)+ 建造者接口(分步设置函数)+ 指挥者(统一构建流程) 实现。
C语言实现建造者模式的思路
- 产品(Product):需要构建的复杂对象(如一个包含多个属性的结构体)。
- 建造者接口(Builder):一组函数指针,定义分步设置产品属性的方法(如设置名称、大小、颜色等)。
- 具体建造者(Concrete Builder):实现建造者接口,负责实际设置产品的属性。
- 指挥者(Director):调用建造者的方法,按固定流程构建产品,隔离客户端与构建细节。
示例:构建复杂的"电脑"对象
假设需要构建一台电脑,包含CPU、内存、硬盘、显卡等可选组件,且不同配置流程可能不同(如办公电脑、游戏电脑)。
步骤1:定义产品(电脑)
c
// 产品:电脑(包含多个组件)
typedef struct {
char cpu[32]; // 处理器
char memory[16]; // 内存
char disk[16]; // 硬盘
char gpu[32]; // 显卡(可选)
char os[16]; // 操作系统
} Computer;
步骤2:定义建造者接口
用结构体封装函数指针,定义构建电脑的分步方法(设置CPU、内存等)和获取最终产品的方法。
c
// 建造者接口(定义分步构建方法)
typedef struct ComputerBuilder {
// 分步设置组件的函数
void (*set_cpu)(struct ComputerBuilder* builder, const char* cpu);
void (*set_memory)(struct ComputerBuilder* builder, const char* memory);
void (*set_disk)(struct ComputerBuilder* builder, const char* disk);
void (*set_gpu)(struct ComputerBuilder* builder, const char* gpu); // 可选
void (*set_os)(struct ComputerBuilder* builder, const char* os);
// 获取最终构建的产品
Computer* (*get_result)(struct ComputerBuilder* builder);
// 内部存储正在构建的产品
Computer product;
} ComputerBuilder;
步骤3:实现具体建造者
以"游戏电脑建造者"为例,实现接口方法(实际中可根据需求定义多个建造者,如办公电脑建造者)。
c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 具体建造者:游戏电脑建造者
// 1. 实现分步设置方法
static void game_builder_set_cpu(ComputerBuilder* builder, const char* cpu) {
strncpy(builder->product.cpu, cpu, sizeof(builder->product.cpu)-1);
}
static void game_builder_set_memory(ComputerBuilder* builder, const char* memory) {
strncpy(builder->product.memory, memory, sizeof(builder->product.memory)-1);
}
static void game_builder_set_disk(ComputerBuilder* builder, const char* disk) {
strncpy(builder->product.disk, disk, sizeof(builder->product.disk)-1);
}
static void game_builder_set_gpu(ComputerBuilder* builder, const char* gpu) {
strncpy(builder->product.gpu, gpu, sizeof(builder->product.gpu)-1);
}
static void game_builder_set_os(ComputerBuilder* builder, const char* os) {
strncpy(builder->product.os, os, sizeof(builder->product.os)-1);
}
// 2. 获取构建结果(返回产品副本,避免外部修改内部状态)
static Computer* game_builder_get_result(ComputerBuilder* builder) {
Computer* result = (Computer*)malloc(sizeof(Computer));
if (result) {
*result = builder->product; // 复制产品数据
}
return result;
}
// 初始化游戏电脑建造者(绑定接口方法)
void game_builder_init(ComputerBuilder* builder) {
builder->set_cpu = game_builder_set_cpu;
builder->set_memory = game_builder_set_memory;
builder->set_disk = game_builder_set_disk;
builder->set_gpu = game_builder_set_gpu;
builder->set_os = game_builder_set_os;
builder->get_result = game_builder_get_result;
// 初始化产品为默认值
memset(&builder->product, 0, sizeof(Computer));
}
步骤4:实现指挥者(Director)
指挥者定义固定的构建流程(如"组装游戏电脑"的步骤),客户端只需调用指挥者,无需关心具体构建细节。
c
// 指挥者:负责按流程构建电脑
typedef struct {
ComputerBuilder* builder; // 依赖建造者接口
} Director;
// 初始化指挥者(绑定建造者)
void director_init(Director* director, ComputerBuilder* builder) {
director->builder = builder;
}
// 指挥者的构建流程:组装游戏电脑
Computer* director_build_game_pc(Director* director) {
// 按固定步骤调用建造者的方法
director->builder->set_cpu(director->builder, "Intel i9-13900K");
director->builder->set_memory(director->builder, "32GB DDR5");
director->builder->set_disk(director->builder, "1TB SSD");
director->builder->set_gpu(director->builder, "NVIDIA RTX 4090");
director->builder->set_os(director->builder, "Windows 11");
// 返回最终产品
return director->builder->get_result(director->builder);
}
步骤5:使用建造者模式
客户端通过指挥者构建产品,无需直接操作建造者的分步方法。
c
// 打印电脑配置
void print_computer(Computer* pc) {
printf("电脑配置:\n");
printf("CPU: %s\n", pc->cpu);
printf("内存: %s\n", pc->memory);
printf("硬盘: %s\n", pc->disk);
printf("显卡: %s\n", pc->gpu);
printf("系统: %s\n", pc->os);
}
int main() {
// 1. 创建并初始化建造者
ComputerBuilder builder;
game_builder_init(&builder);
// 2. 创建指挥者,绑定建造者
Director director;
director_init(&director, &builder);
// 3. 指挥者按流程构建产品
Computer* game_pc = director_build_game_pc(&director);
// 4. 使用产品
if (game_pc) {
print_computer(game_pc);
free(game_pc); // 释放产品内存
}
return 0;
}
输出结果
电脑配置:
CPU: Intel i9-13900K
内存: 32GB DDR5
硬盘: 1TB SSD
显卡: NVIDIA RTX 4090
系统: Windows 11
扩展:支持多种建造者
如果需要构建"办公电脑",只需新增一个具体建造者(如office_builder),实现自己的set_*方法,指挥者可以复用或新增流程:
c
// 示例:办公电脑建造者的初始化(简化)
void office_builder_init(ComputerBuilder* builder) {
// 绑定与游戏电脑不同的实现(如低配CPU、集成显卡)
builder->set_cpu = office_builder_set_cpu;
// ... 其他方法类似 ...
}
// 指挥者新增办公电脑构建流程
Computer* director_build_office_pc(Director* director) {
director->builder->set_cpu(director->builder, "Intel i5-13400");
director->builder->set_memory(director->builder, "16GB DDR4");
// ... 其他步骤 ...
return director->builder->get_result(director->builder);
}
核心思想总结
- 分离构建与表示:产品的构建步骤(建造者)与最终形态(产品)分离,同一构建过程可生成不同产品。
- 分步构建 :通过多个
set_*方法逐步设置属性,避免多参数构造函数的混乱(如Computer* create(int cpu, int mem, ...))。 - 灵活性:新增产品类型时,只需新增具体建造者,指挥者和客户端代码无需修改(符合开放-封闭原则)。
C语言通过结构体和函数指针模拟了建造者模式的核心逻辑,适合构建参数复杂、配置多样的对象(如配置文件、网络请求、复杂数据结构等)。