建造者模式及优化
建造者模式是一种创建型设计模式,它将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。核心思想是指挥者定流程,建造者填细节,通过多个步骤逐步构建对象,并允许灵活组合这些步骤以生成不同配置的对象。通过将复杂对象的构建步骤抽象化,实现了"流程固定、配置可变"的灵活创建方式。
介绍
核心角色
- 产品(Product):被构建的复杂对象(如电脑、汽车)。
- 抽象建造者(Abstract Builder):定义构建产品的抽象方法(步骤)和返回产品的接口。
- 具体建造者(Concrete Builder):实现抽象建造者的方法,完成具体的构建步骤,并提供获取产品的方式。
- 指挥者(Director):控制构建流程(调用建造者的步骤),隔离客户端与构建过程。
优点
- 分离构建与表示:构建流程(指挥者)与具体部件配置(建造者)分离,便于扩展新产品。
- 灵活定制:通过更换具体建造者,可在不改变流程的情况下生成不同配置的对象。
- 精确控制构建过程:分步构建允许在每个步骤中加入校验或逻辑,确保对象正确构建。
- 代码复用:公共构建流程在指挥者中实现,避免重复编码。
适用场景
- 构建复杂对象
当对象包含多个部件(如电脑、汽车、文档),且构建步骤固定但部件配置可变时(如不同配置的电脑)。 - 需要多种表示形式
同一构建流程需生成不同产品(如同一文档模板生成PDF、Word、HTML版本)。 - 构建过程需精细控制
需分步构建对象,或需要在构建过程中调整步骤(如先装CPU再装内存,顺序不可乱)。
实现
以组装电脑为例,电脑包含CPU、内存、显卡等部件,用户可定制不同配置(如办公电脑、游戏电脑),适合用建造者模式分离"组装流程"和"具体配置"。
#include <string>
#include <iostream>
#include <vector>// 产品:电脑
class Computer {
private:std::string cpu; // 处理器std::string memory; // 内存std::string graphics; // 显卡std::string storage; // 存储
public:void setCPU(const std::string& c) { cpu = c; }void setMemory(const std::string& m) { memory = m; }void setGraphics(const std::string& g) { graphics = g; }void setStorage(const std::string& s) { storage = s; }// 展示电脑配置void showInfo() const {std::cout << "CPU: " << cpu << "\n"<< "内存: " << memory << "\n"<< "显卡: " << graphics << "\n"<< "存储: " << storage << std::endl;}
};// 抽象建造者:定义电脑组装步骤
class ComputerBuilder {
public:virtual ~ComputerBuilder() = default;virtual void buildCPU() = 0; // 构建CPUvirtual void buildMemory() = 0; // 构建内存virtual void buildGraphics() = 0; // 构建显卡virtual void buildStorage() = 0; // 构建存储virtual Computer* getResult() = 0; // 返回组装好的电脑
};// 具体建造者1:办公电脑
class OfficeComputerBuilder : public ComputerBuilder {
private:Computer* computer; // 正在构建的电脑
public:OfficeComputerBuilder() { computer = new Computer(); }~OfficeComputerBuilder() override { delete computer; }void buildCPU() override {computer->setCPU("Intel i5"); // 办公级CPU}void buildMemory() override {computer->setMemory("16GB DDR4"); // 中等内存}void buildGraphics() override {computer->setGraphics("集成显卡"); // 无需独立显卡}void buildStorage() override {computer->setStorage("512GB SSD"); // 够用的存储}Computer* getResult() override {return computer; // 返回构建好的电脑(转移所有权)}
};// 具体建造者2:游戏电脑
class GameComputerBuilder : public ComputerBuilder {
private:Computer* computer;
public:GameComputerBuilder() { computer = new Computer(); }~GameComputerBuilder() override { delete computer; }void buildCPU() override {computer->setCPU("Intel i9"); // 高性能CPU}void buildMemory() override {computer->setMemory("32GB DDR5"); // 大容量高速内存}void buildGraphics() override {computer->setGraphics("NVIDIA RTX 4090"); // 顶级显卡}void buildStorage() override {computer->setStorage("2TB SSD"); // 大容量存储}Computer* getResult() override {return computer;}
};// 指挥者:控制构建流程
class Director {
private:ComputerBuilder* builder; // 指向当前建造者
public:explicit Director(ComputerBuilder* b) : builder(b) {}// 切换建造者void setBuilder(ComputerBuilder* b) {builder = b;}// 执行构建流程(固定步骤)Computer* construct() {builder->buildCPU();builder->buildMemory();builder->buildGraphics();builder->buildStorage();return builder->getResult(); // 返回最终产品}
};int main() {// 1. 创建具体建造者(办公电脑)ComputerBuilder* officeBuilder = new OfficeComputerBuilder();Director director(officeBuilder); // 指挥者控制构建流程Computer* officePC = director.construct(); // 执行构建std::cout << "=== 办公电脑配置 ===" << std::endl;officePC->showInfo();// 2. 创建具体建造者(游戏电脑)ComputerBuilder* gameBuilder = new GameComputerBuilder();director.setBuilder(gameBuilder); // 切换建造者Computer* gamePC = director.construct();std::cout << "\n=== 游戏电脑配置 ===" << std::endl;gamePC->showInfo();// 清理资源delete officePC;delete gamePC;delete officeBuilder;delete gameBuilder;return 0;
}
输出结果
=== 办公电脑配置 ===
CPU: Intel i5
内存: 16GB DDR4
显卡: 集成显卡
存储: 512GB SSD=== 游戏电脑配置 ===
CPU: Intel i9
内存: 32GB DDR5
显卡: NVIDIA RTX 4090
存储: 2TB SSD
应用场景
- 产品配置
- 电子产品组装(如电脑、手机的不同型号配置)。
- 汽车制造(同一车型的标准版、豪华版、运动版)。
- 文档生成
- 报告生成工具(同一内容生成PDF、Markdown、HTML格式)。
- 代码生成器(根据模板生成不同语言的代码)。
- 复杂对象创建
- 游戏角色创建(同一角色模型,不同装备、技能配置)。
- 数据库连接池(不同参数配置的连接对象)。
- 框架与库
- C++ STL中的
stringstream
(分步构建字符串)。 - 建造者模式在JSON/XML解析器中用于构建树形结构。
- C++ STL中的
优化
优化方向
- 支持动态自定义配置:允许客户端灵活设置每个部件(而非局限于预设的“办公/游戏”配置)。
- 引入可选部件与校验:支持非必需部件(如散热器、声卡),并添加部件兼容性校验。
- 使用智能指针管理资源:避免手动内存管理,防止内存泄漏。
- 流畅接口(Fluent Interface):通过链式调用简化建造过程,提升代码可读性。
- 指挥者功能增强:支持自定义构建流程(如可选步骤、步骤顺序调整)。
#include <string>
#include <iostream>
#include <vector>
#include <memory> // 智能指针
#include <stdexcept> // 异常处理// 产品:电脑(支持更多部件和兼容性校验)
class Computer {
private:std::string cpu;std::string memory;std::string graphics; // 可选:集成/独立显卡std::string storage;std::string cooler; // 可选:散热器std::vector<std::string> compatibleCPUs = {"Intel i5", "Intel i9", "AMD Ryzen 5"};std::vector<std::string> compatibleMemories = {"16GB DDR4", "32GB DDR5", "64GB DDR5"};public:// 链式设置方法(Fluent Interface)Computer& setCPU(const std::string& c) { // 校验CPU兼容性if (std::find(compatibleCPUs.begin(), compatibleCPUs.end(), c) == compatibleCPUs.end()) {throw std::invalid_argument("不支持的CPU型号:" + c);}cpu = c; return *this; }Computer& setMemory(const std::string& m) { if (std::find(compatibleMemories.begin(), compatibleMemories.end(), m) == compatibleMemories.end()) {throw std::invalid_argument("不支持的内存型号:" + m);}memory = m; return *this; }Computer& setGraphics(const std::string& g) { graphics = g; return *this; }Computer& setStorage(const std::string& s) { storage = s; return *this; }Computer& setCooler(const std::string& c) { cooler = c; return *this; }// 展示配置(包含可选部件)void showInfo() const {std::cout << "CPU: " << cpu << "\n"<< "内存: " << memory << "\n"<< "显卡: " << (graphics.empty() ? "无(集成)" : graphics) << "\n"<< "存储: " << storage << "\n"<< "散热器: " << (cooler.empty() ? "无(默认)" : cooler) << std::endl;}// 校验必填部件是否齐全bool isValid() const {return !cpu.empty() && !memory.empty() && !storage.empty();}
};// 抽象建造者(支持链式调用和智能指针)
class ComputerBuilder {
public:using Ptr = std::unique_ptr<ComputerBuilder>; // 智能指针管理virtual ~ComputerBuilder() = default;// 纯虚方法:构建步骤(支持链式返回)virtual ComputerBuilder& buildCPU() = 0;virtual ComputerBuilder& buildMemory() = 0;virtual ComputerBuilder& buildGraphics() { return *this; } // 可选步骤(默认空实现)virtual ComputerBuilder& buildStorage() = 0;virtual ComputerBuilder& buildCooler() { return *this; } // 可选步骤// 返回产品(智能指针,自动释放)virtual std::unique_ptr<Computer> getResult() {if (!computer->isValid()) {throw std::logic_error("电脑配置不完整,缺少必填部件");}return std::move(computer); // 转移所有权}protected:std::unique_ptr<Computer> computer = std::make_unique<Computer>(); // 产品
};// 具体建造者1:办公电脑(基础配置,可选散热器)
class OfficeComputerBuilder : public ComputerBuilder {
public:ComputerBuilder& buildCPU() override {computer->setCPU("Intel i5");return *this;}ComputerBuilder& buildMemory() override {computer->setMemory("16GB DDR4");return *this;}// 办公电脑默认无独立显卡(使用集成),无需重写buildGraphicsComputerBuilder& buildStorage() override {computer->setStorage("512GB SSD");return *this;}// 可选:为办公电脑添加低端散热器ComputerBuilder& buildCooler() override {computer->setCooler("基础风冷散热器");return *this;}
};// 具体建造者2:游戏电脑(高性能配置,强制独立显卡和散热器)
class GameComputerBuilder : public ComputerBuilder {
public:ComputerBuilder& buildCPU() override {computer->setCPU("Intel i9");return *this;}ComputerBuilder& buildMemory() override {computer->setMemory("32GB DDR5");return *this;}// 游戏电脑必须有独立显卡(重写为强制步骤)ComputerBuilder& buildGraphics() override {computer->setGraphics("NVIDIA RTX 4090");return *this;}ComputerBuilder& buildStorage() override {computer->setStorage("2TB SSD");return *this;}// 游戏电脑必须有高性能散热器ComputerBuilder& buildCooler() override {computer->setCooler("水冷散热器");return *this;}
};// 具体建造者3:自定义建造者(允许客户端自由配置)
class CustomComputerBuilder : public ComputerBuilder {
public:// 空实现,由客户端手动调用产品的set方法配置ComputerBuilder& buildCPU() override { return *this; }ComputerBuilder& buildMemory() override { return *this; }ComputerBuilder& buildStorage() override { return *this; }// 提供直接访问产品的接口(用于自定义配置)Computer* getComputer() { return computer.get(); }
};// 指挥者(支持灵活流程和可选步骤)
class Director {
public:// 构建基础电脑(必填部件:CPU、内存、存储)std::unique_ptr<Computer> buildBasic(ComputerBuilder::Ptr builder) {builder->buildCPU()->buildMemory()->buildStorage();return builder->getResult();}// 构建完整电脑(包含可选部件)std::unique_ptr<Computer> buildFull(ComputerBuilder::Ptr builder) {builder->buildCPU()->buildMemory()->buildGraphics()->buildStorage()->buildCooler();return builder->getResult();}// 自定义流程(按传入的步骤函数执行)using StepFunc = std::function<void(ComputerBuilder*)>;std::unique_ptr<Computer> buildCustom(ComputerBuilder::Ptr builder, const std::vector<StepFunc>& steps) {for (const auto& step : steps) {step(builder.get());}return builder->getResult();}
};int main() {try {Director director;// 1. 构建办公电脑(基础配置)std::cout << "=== 办公电脑(基础配置) ===" << std::endl;auto officeBasic = director.buildBasic(std::make_unique<OfficeComputerBuilder>());officeBasic->showInfo();// 2. 构建游戏电脑(完整配置)std::cout << "\n=== 游戏电脑(完整配置) ===" << std::endl;auto gameFull = director.buildFull(std::make_unique<GameComputerBuilder>());gameFull->showInfo();// 3. 自定义电脑(自由配置部件)std::cout << "\n=== 自定义电脑 ===" << std::endl;auto customBuilder = std::make_unique<CustomComputerBuilder>();// 直接配置产品的具体部件(链式调用)customBuilder->getComputer()->setCPU("AMD Ryzen 5")->setMemory("64GB DDR5")->setGraphics("AMD Radeon RX 7900")->setStorage("4TB SSD")->setCooler("高端风冷散热器");// 用指挥者构建(此处仅做校验)auto customPC = director.buildBasic(std::move(customBuilder));customPC->showInfo();// 4. 自定义构建流程(动态指定步骤)std::cout << "\n=== 动态流程构建(仅CPU+内存+存储) ===" << std::endl;auto dynamicBuilder = std::make_unique<CustomComputerBuilder>();dynamicBuilder->getComputer()->setCPU("Intel i5")->setMemory("32GB DDR4")->setStorage("1TB SSD");// 定义自定义步骤(仅执行CPU和内存校验)std::vector<Director::StepFunc> steps = {[](ComputerBuilder* b) { b->buildCPU(); }, // 实际是校验CPU已设置[](ComputerBuilder* b) { b->buildMemory(); } // 校验内存已设置};auto dynamicPC = director.buildCustom(std::move(dynamicBuilder), steps);dynamicPC->showInfo();} catch (const std::exception& e) {std::cerr << "错误:" << e.what() << std::endl;return 1;}return 0;
}
输出结果
=== 办公电脑(基础配置) ===
CPU: Intel i5
内存: 16GB DDR4
显卡: 无(集成)
存储: 512GB SSD
散热器: 无(默认)=== 游戏电脑(完整配置) ===
CPU: Intel i9
内存: 32GB DDR5
显卡: NVIDIA RTX 4090
存储: 2TB SSD
散热器: 水冷散热器=== 自定义电脑 ===
CPU: AMD Ryzen 5
内存: 64GB DDR5
显卡: AMD Radeon RX 7900
存储: 4TB SSD
散热器: 高端风冷散热器=== 动态流程构建(仅CPU+内存+存储) ===
CPU: Intel i5
内存: 32GB DDR4
显卡: 无(集成)
存储: 1TB SSD
散热器: 无(默认)
优化点说明
- 动态自定义配置
- 新增
CustomComputerBuilder
,允许客户端通过getComputer()
直接访问产品,自由设置部件(如setCPU("AMD Ryzen 5")
),突破预设配置的限制。 - 配合链式调用(
obj->setA()->setB()
),使配置代码更简洁直观。
- 新增
- 可选部件与校验机制
- 将显卡、散热器设为可选部件,抽象建造者中提供默认空实现,具体建造者按需重写(如游戏电脑必须实现
buildGraphics
)。 - 产品内部添加兼容性校验(如
compatibleCPUs
)和完整性校验(isValid()
),避免无效配置(如使用不支持的CPU型号)。
- 将显卡、散热器设为可选部件,抽象建造者中提供默认空实现,具体建造者按需重写(如游戏电脑必须实现
- 智能指针与资源安全
- 使用
std::unique_ptr
管理建造者和产品的生命周期,无需手动delete
,彻底避免内存泄漏。 - 产品所有权通过
std::move
转移,明确资源归属。
- 使用
- 指挥者功能增强
- 提供多种预设流程(
buildBasic
基础配置、buildFull
完整配置),满足不同场景需求。 - 支持自定义流程(
buildCustom
),通过函数对象动态指定步骤,灵活度极高(如仅构建CPU+内存+存储)。
- 提供多种预设流程(
- 扩展性提升
- 新增部件(如未来添加“声卡”)时,只需在
Computer
中添加setSoundCard
方法,抽象建造者中添加默认空实现,无需修改现有建造者和指挥者,符合开闭原则。
- 新增部件(如未来添加“声卡”)时,只需在
优点
- 更高的灵活性:支持预设配置、完全自定义配置、动态流程配置,适应多样化需求。
- 更强的安全性:智能指针自动管理内存,校验机制避免无效配置,异常处理明确错误原因。
- 更好的扩展性:新增部件或流程时,对现有代码侵入性极小,易于维护。
- 更优的易用性:链式调用和多样化构建接口降低使用门槛,客户端可按需选择复杂度。
适用场景
- 复杂产品定制平台:如电商网站的“自定义PC”功能,用户可自由选择每个部件,系统自动校验兼容性。
- 动态报表生成:允许用户选择报表包含的模块(表格、图表、摘要),按自定义顺序组装。
- 游戏角色创建器:玩家可选择角色的种族、职业、技能、装备,系统确保选择组合有效(如某些技能仅特定种族可用)。