创建型模式
生成器模式(Builder Pattern)是一种创建型设计模式,它专注于将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。
就像是做饭,你可以自己慢慢做,各个步骤自己选择。而使用生成器就像是预制菜,所有的最后菜的样子,已经规划好了。你只能从中选择一个。
为什么需要生成器模式?
当我们需要创建具有复杂内部结构的对象(比如包含多个部件、构建步骤繁琐或有多种配置方式的对象)时,直接在构造函数中处理会导致:
- 构造函数参数过多,难以维护(比如创建一个 "电脑" 对象,需要指定 CPU、内存、硬盘、显卡等十几种参数);
- 不同配置的对象需要不同的构建逻辑,导致代码臃肿;
- 构建过程与对象表示耦合,无法灵活切换不同的构建方式
举个生活中的例子
想象你去电脑店组装一台电脑,整个过程其实很复杂:
- 需要选很多零件(CPU、内存、硬盘、显卡等);
- 零件之间有搭配要求(比如主板要兼容 CPU);
- 组装有固定步骤(先装主板,再插 CPU,最后装机箱);
- 不同需求选的零件不同(办公用不需要好显卡,游戏用需要大内存)。
如果没有生成器模式,就像你自己去买零件、自己组装:
- 要记住所有零件型号和搭配规则,很容易出错;
- 每次换配置(比如从办公电脑换成游戏电脑),都要重新学一遍选零件和组装的流程;
- 步骤错了(比如先装显卡再装主板),可能装不上。
生成器模式就像请了一个专业装机师傅(生成器)和一个客户经理(指挥者):
- 你只需要告诉客户经理 "我要一台办公电脑",不用管具体零件和步骤;
- 装机师傅知道所有零件搭配规则和组装顺序,会按步骤一步步装好;
- 想换游戏电脑?换一个擅长装游戏电脑的师傅(另一个生成器)就行,你不用学新东西。
示例
cpp
#include <iostream>
#include <string>
// 最终产品:电脑
class Computer {
private:
std::string cpu_; // 处理器
std::string memory_; // 内存
std::string hardDisk_; // 硬盘
std::string graphics_; // 显卡
std::string power_; // 电源
public:
// 设置各部件(让生成器可以修改内部属性)
void setCPU(const std::string& cpu) { cpu_ = cpu; }
void setMemory(const std::string& memory) { memory_ = memory; }
void setHardDisk(const std::string& hardDisk) { hardDisk_ = hardDisk; }
void setGraphics(const std::string& graphics) { graphics_ = graphics; }
void setPower(const std::string& power) { power_ = power; }
// 获取各部件信息
std::string getCPU() const { return cpu_; }
std::string getMemory() const { return memory_; }
std::string getHardDisk() const { return hardDisk_; }
std::string getGraphics() const { return graphics_; }
std::string getPower() const { return power_; }
// 显示电脑配置
void showConfig() const {
std::cout << "电脑配置:\n";
std::cout << "CPU:" << cpu_ << "\n";
std::cout << "内存:" << memory_ << "\n";
std::cout << "硬盘:" << hardDisk_ << "\n";
std::cout << "显卡:" << graphics_ << "\n";
std::cout << "电源:" << power_ << "\n\n";
}
};
// 生成器接口(抽象类):定义组装步骤
class Builder {
protected:
Computer computer_; // 正在组装的电脑
public:
// 纯虚函数:组装各部件的步骤
virtual void buildCPU() = 0;
virtual void buildMemory() = 0;
virtual void buildHardDisk() = 0;
virtual void buildGraphics() = 0;
virtual void buildPower() = 0;
// 返回组装好的电脑
virtual Computer getComputer() {
return computer_;
}
// 虚析构函数
virtual ~Builder() = default;
};
// 具体生成器1:办公电脑生成器
class OfficeBuilder : public Builder {
public:
void buildCPU() override {
computer_.setCPU("英特尔 i5(入门级)");
std::cout << "安装办公电脑CPU:" << computer_.getCPU() << "\n";
}
void buildMemory() override {
computer_.setMemory("8G DDR4");
std::cout << "安装办公电脑内存:" << computer_.getMemory() << "\n";
}
void buildHardDisk() override {
computer_.setHardDisk("512G 固态硬盘");
std::cout << "安装办公电脑硬盘:" << computer_.getHardDisk() << "\n";
}
void buildGraphics() override {
computer_.setGraphics("集成显卡");
std::cout << "安装办公电脑显卡:" << computer_.getGraphics() << "\n";
}
void buildPower() override {
computer_.setPower("300W 电源");
std::cout << "安装办公电脑电源:" << computer_.getPower() << "\n";
}
};
// 具体生成器2:游戏电脑生成器
class GameBuilder : public Builder {
public:
void buildCPU() override {
computer_.setCPU("英特尔 i7(高性能)");
std::cout << "安装游戏电脑CPU:" << computer_.getCPU() << "\n";
}
void buildMemory() override {
computer_.setMemory("16G DDR5");
std::cout << "安装游戏电脑内存:" << computer_.getMemory() << "\n";
}
void buildHardDisk() override {
computer_.setHardDisk("1T 固态硬盘");
std::cout << "安装游戏电脑硬盘:" << computer_.getHardDisk() << "\n";
}
void buildGraphics() override {
computer_.setGraphics("RTX 4060 独立显卡");
std::cout << "安装游戏电脑显卡:" << computer_.getGraphics() << "\n";
}
void buildPower() override {
computer_.setPower("500W 电源");
std::cout << "安装游戏电脑电源:" << computer_.getPower() << "\n";
}
};
// 指挥者:负责控制组装流程
class Director {
private:
Builder* builder_; // 指向当前使用的生成器
public:
// 构造函数:传入生成器
Director(Builder* builder) : builder_(builder) {}
// 指挥组装电脑(固定步骤)
Computer construct() {
std::cout << "开始组装电脑...\n";
builder_->buildCPU();
builder_->buildMemory();
builder_->buildHardDisk();
builder_->buildGraphics();
builder_->buildPower();
std::cout << "组装完成!\n\n";
return builder_->getComputer();
}
};
// 客户端:用户购买电脑
int main() {
// 1. 准备生成器(装机师傅)
OfficeBuilder officeBuilder; // 办公电脑装机师傅
GameBuilder gameBuilder; // 游戏电脑装机师傅
// 2. 准备指挥者(客户经理)
Director director(nullptr);
// 3. 组装办公电脑
std::cout << "=== 组装办公电脑 ===\n";
director = Director(&officeBuilder); // 安排办公装机师傅
Computer officeComputer = director.construct(); // 开始组装
officeComputer.showConfig(); // 查看配置
// 4. 组装游戏电脑
std::cout << "=== 组装游戏电脑 ===\n";
director = Director(&gameBuilder); // 换游戏装机师傅
Computer gameComputer = director.construct(); // 开始组装
gameComputer.showConfig(); // 查看配置
return 0;
}
当然。有些参数是不一定使用的,可以选择使用哪些。那么这里给出第二个示例,用于参考,额外的参数配置部分。
cpp
#include <iostream>
#include <string>
#include <vector>
// 电脑产品(支持可选配件)
class Computer {
private:
std::string cpu_; // 必选:CPU
std::string memory_; // 必选:内存
std::string hardDisk_; // 必选:硬盘
std::string graphics_; // 可选:显卡(核显/独显)
std::string power_; // 必选:电源
std::vector<std::string> extras_; // 可选:额外配件(如散热器、蓝牙模块)
public:
// 设置必选部件
void setCPU(const std::string& cpu) { cpu_ = cpu; }
void setMemory(const std::string& memory) { memory_ = memory; }
void setHardDisk(const std::string& hardDisk) { hardDisk_ = hardDisk; }
void setPower(const std::string& power) { power_ = power; }
// 设置可选部件
void setGraphics(const std::string& graphics) { graphics_ = graphics; }
void addExtra(const std::string& extra) { extras_.push_back(extra); }
// 获取部件信息(用于生成器输出)
std::string getCPU() const { return cpu_; }
std::string getMemory() const { return memory_; }
std::string getHardDisk() const { return hardDisk_; }
std::string getGraphics() const { return graphics_; }
std::string getPower() const { return power_; }
// 显示配置(区分必选和可选)
void showConfig() const {
std::cout << "===== 电脑配置 =====" << "\n";
std::cout << "【必选部件】\n";
std::cout << "CPU:" << cpu_ << "\n";
std::cout << "内存:" << memory_ << "\n";
std::cout << "硬盘:" << hardDisk_ << "\n";
std::cout << "电源:" << power_ << "\n";
std::cout << "\n【可选部件】\n";
std::cout << "显卡:" << (graphics_.empty() ? "无(使用核显)" : graphics_) << "\n";
std::cout << "额外配件:";
if (extras_.empty()) {
std::cout << "无";
}
else {
for (const auto& extra : extras_) {
std::cout << extra << "、";
}
}
std::cout << "\n====================\n\n";
}
};
// 生成器接口(支持可选步骤)
class Builder {
protected:
Computer computer_;
public:
// 必选步骤(纯虚函数,必须实现)
virtual void buildCPU() = 0;
virtual void buildMemory() = 0;
virtual void buildHardDisk() = 0;
virtual void buildPower() = 0;
// 可选步骤(虚函数,默认空实现,可选择性重写)
virtual void buildGraphics() {} // 可选:装独立显卡
virtual void addExtra(const std::string& extra) { // 可选:加配件
computer_.addExtra(extra);
}
virtual Computer getComputer() { return computer_; }
virtual ~Builder() = default;
};
// 具体生成器1:极简办公电脑(不选独显,不加额外配件)
class MinimalOfficeBuilder : public Builder {
public:
void buildCPU() override {
computer_.setCPU("英特尔 i3(低功耗)");
std::cout << "安装CPU:" << computer_.getCPU() << "\n";
}
void buildMemory() override {
computer_.setMemory("4G DDR4");
std::cout << "安装内存:" << computer_.getMemory() << "\n";
}
void buildHardDisk() override {
computer_.setHardDisk("256G 固态硬盘");
std::cout << "安装硬盘:" << computer_.getHardDisk() << "\n";
}
void buildPower() override {
computer_.setPower("200W 电源");
std::cout << "安装电源:" << computer_.getPower() << "\n";
}
// 不重写buildGraphics(),使用默认空实现(不装独显)
// 不调用addExtra(),所以无额外配件
};
// 具体生成器2:高端游戏电脑(选独显,加多个配件)
class HighEndGameBuilder : public Builder {
public:
void buildCPU() override {
computer_.setCPU("AMD Ryzen 9(旗舰级)");
std::cout << "安装CPU:" << computer_.getCPU() << "\n";
}
void buildMemory() override {
computer_.setMemory("32G DDR5");
std::cout << "安装内存:" << computer_.getMemory() << "\n";
}
void buildHardDisk() override {
computer_.setHardDisk("2T 固态硬盘");
std::cout << "安装硬盘:" << computer_.getHardDisk() << "\n";
}
void buildPower() override {
computer_.setPower("800W 金牌电源");
std::cout << "安装电源:" << computer_.getPower() << "\n";
}
// 重写可选步骤:安装独显
void buildGraphics() override {
computer_.setGraphics("RTX 4090 独显");
std::cout << "安装显卡:" << computer_.getGraphics() << "\n";
}
};
// 指挥者(支持灵活调整步骤)
class Director {
private:
Builder* builder_;
public:
Director(Builder* builder) : builder_(builder) {}
// 基础组装(只包含必选步骤)
Computer buildBasic() {
std::cout << "=== 开始基础组装(必选部件)===\n";
builder_->buildCPU();
builder_->buildMemory();
builder_->buildHardDisk();
builder_->buildPower();
std::cout << "基础组装完成!\n";
return builder_->getComputer();
}
// 完整组装(必选+可选步骤)
Computer buildComplete() {
std::cout << "\n=== 开始完整组装(必选+可选)===\n";
Computer basic = buildBasic(); // 复用基础组装逻辑
builder_->buildGraphics(); // 可选:装显卡
builder_->addExtra("水冷散热器"); // 可选:加配件
builder_->addExtra("蓝牙模块"); // 可选:加配件
std::cout << "完整组装完成!\n";
return builder_->getComputer();
}
};
// 客户端:灵活定制不同配置
int main() {
// 1. 组装极简办公电脑(只装必选部件)
MinimalOfficeBuilder officeBuilder;
Director officeDirector(&officeBuilder);
Computer officePC = officeDirector.buildBasic(); // 只调用必选步骤
officePC.showConfig();
// 2. 组装高端游戏电脑(必选+可选部件)
HighEndGameBuilder gameBuilder;
Director gameDirector(&gameBuilder);
Computer gamePC = gameDirector.buildComplete(); // 调用必选+可选步骤
gamePC.showConfig();
// 3. 临时加配件(生成器模式支持中途调整)
std::cout << "给办公电脑临时加一个配件:\n";
officeBuilder.addExtra("无线网卡");
officePC = officeBuilder.getComputer();
officePC.showConfig();
return 0;
}
优势
1.使用生成器模式可避免 "重叠构造函数 (telescoping constructor)" 的出现。
假设你的构造函数中有十个可选参数, 那么调用该函数会非常不方便; 因此, 你需要重载这个构造函数, 新建几个只有较少参数的简化版。 但这些构造函数仍需调用主构造函数, 传递一些默认数值来替代省略掉的参数。
cpp
class Pizza {
Pizza(int size) { ...... }
Pizza(int size, boolean cheese) { ...... }
Pizza(int size, boolean cheese, boolean pepperoni) { ...... }
//............
生成器模式让你可以分步骤生成对象, 而且允许你仅使用必须的步骤。 应用该模式后, 你再也不需要将几十个参数塞进构造函数里了。