用C语言实现建造者模式
建造者模式(Builder Pattern)的核心是将复杂对象的构建过程与表示分离,通过分步设置属性来创建对象,适合构建具有多个可选参数或复杂初始化逻辑的对象。在C语言中,可以通过结构体(表示对象)+ 建造者接口(分步设置函数)+ 指挥者(统一构建流程) 实现。
C语言实现建造者模式的思路
- 产品(Product):需要构建的复杂对象(如一个包含多个属性的结构体)。
- 建造者接口(Builder):一组函数指针,定义分步设置产品属性的方法(如设置名称、大小、颜色等)。
- 具体建造者(Concrete Builder):实现建造者接口,负责实际设置产品的属性。
- 指挥者(Director):调用建造者的方法,按固定流程构建产品,隔离客户端与构建细节。
示例:构建复杂的“电脑”对象
假设需要构建一台电脑,包含CPU、内存、硬盘、显卡等可选组件,且不同配置流程可能不同(如办公电脑、游戏电脑)。
步骤1:定义产品(电脑)
// 产品:电脑(包含多个组件)
typedef struct {char cpu[32]; // 处理器char memory[16]; // 内存char disk[16]; // 硬盘char gpu[32]; // 显卡(可选)char os[16]; // 操作系统
} Computer;
步骤2:定义建造者接口
用结构体封装函数指针,定义构建电脑的分步方法(设置CPU、内存等)和获取最终产品的方法。
// 建造者接口(定义分步构建方法)
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:实现具体建造者
以“游戏电脑建造者”为例,实现接口方法(实际中可根据需求定义多个建造者,如办公电脑建造者)。
#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)
指挥者定义固定的构建流程(如“组装游戏电脑”的步骤),客户端只需调用指挥者,无需关心具体构建细节。
// 指挥者:负责按流程构建电脑
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:使用建造者模式
客户端通过指挥者构建产品,无需直接操作建造者的分步方法。
// 打印电脑配置
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_*
方法,指挥者可以复用或新增流程:
// 示例:办公电脑建造者的初始化(简化)
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语言通过结构体和函数指针模拟了建造者模式的核心逻辑,适合构建参数复杂、配置多样的对象(如配置文件、网络请求、复杂数据结构等)。