创建型模式
生成器模式(Builder Pattern)是一种创建型设计模式,它专注于将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。
就像是做饭,你可以自己慢慢做,各个步骤自己选择。而使用生成器就像是预制菜,所有的最后菜的样子,已经规划好了。你只能从中选择一个。
为什么需要生成器模式?
当我们需要创建具有复杂内部结构的对象(比如包含多个部件、构建步骤繁琐或有多种配置方式的对象)时,直接在构造函数中处理会导致:
- 构造函数参数过多,难以维护(比如创建一个 "电脑" 对象,需要指定 CPU、内存、硬盘、显卡等十几种参数);
- 不同配置的对象需要不同的构建逻辑,导致代码臃肿;
- 构建过程与对象表示耦合,无法灵活切换不同的构建方式
举个生活中的例子
想象你去电脑店组装一台电脑,整个过程其实很复杂:
- 需要选很多零件(CPU、内存、硬盘、显卡等);
- 零件之间有搭配要求(比如主板要兼容 CPU);
- 组装有固定步骤(先装主板,再插 CPU,最后装机箱);
- 不同需求选的零件不同(办公用不需要好显卡,游戏用需要大内存)。
如果没有生成器模式,就像你自己去买零件、自己组装:
- 要记住所有零件型号和搭配规则,很容易出错;
- 每次换配置(比如从办公电脑换成游戏电脑),都要重新学一遍选零件和组装的流程;
- 步骤错了(比如先装显卡再装主板),可能装不上。
生成器模式就像请了一个专业装机师傅(生成器)和一个客户经理(指挥者):
- 你只需要告诉客户经理 “我要一台办公电脑”,不用管具体零件和步骤;
- 装机师傅知道所有零件搭配规则和组装顺序,会按步骤一步步装好;
- 想换游戏电脑?换一个擅长装游戏电脑的师傅(另一个生成器)就行,你不用学新东西。
示例
#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;
}
当然。有些参数是不一定使用的,可以选择使用哪些。那么这里给出第二个示例,用于参考,额外的参数配置部分。
#include <iostream>
#include <string>
#include <vector>// 电脑产品(支持可选配件)
class Computer {
private:std::string cpu_; // 必选:CPUstd::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)” 的出现。
假设你的构造函数中有十个可选参数, 那么调用该函数会非常不方便; 因此, 你需要重载这个构造函数, 新建几个只有较少参数的简化版。 但这些构造函数仍需调用主构造函数, 传递一些默认数值来替代省略掉的参数。
class Pizza {Pizza(int size) { …… }Pizza(int size, boolean cheese) { …… }Pizza(int size, boolean cheese, boolean pepperoni) { …… }
//............
生成器模式让你可以分步骤生成对象, 而且允许你仅使用必须的步骤。 应用该模式后, 你再也不需要将几十个参数塞进构造函数里了。