c++注意点(12)----设计模式(生成器)

创建型模式

生成器模式(Builder Pattern)是一种创建型设计模式,它专注于将复杂对象的构建过程与表示分离,使得同样的构建过程可以创建不同的表示。

就像是做饭,你可以自己慢慢做,各个步骤自己选择。而使用生成器就像是预制菜,所有的最后菜的样子,已经规划好了。你只能从中选择一个。

为什么需要生成器模式?

当我们需要创建具有复杂内部结构的对象(比如包含多个部件、构建步骤繁琐或有多种配置方式的对象)时,直接在构造函数中处理会导致:

  • 构造函数参数过多,难以维护(比如创建一个 "电脑" 对象,需要指定 CPU、内存、硬盘、显卡等十几种参数);
  • 不同配置的对象需要不同的构建逻辑,导致代码臃肿;
  • 构建过程与对象表示耦合,无法灵活切换不同的构建方式

举个生活中的例子

想象你去电脑店组装一台电脑,整个过程其实很复杂:

  1. 需要选很多零件(CPU、内存、硬盘、显卡等);
  2. 零件之间有搭配要求(比如主板要兼容 CPU);
  3. 组装有固定步骤(先装主板,再插 CPU,最后装机箱);
  4. 不同需求选的零件不同(办公用不需要好显卡,游戏用需要大内存)。

如果没有生成器模式,就像你自己去买零件、自己组装:

  • 要记住所有零件型号和搭配规则,很容易出错;
  • 每次换配置(比如从办公电脑换成游戏电脑),都要重新学一遍选零件和组装的流程;
  • 步骤错了(比如先装显卡再装主板),可能装不上。

生成器模式就像请了一个专业装机师傅(生成器)和一个客户经理(指挥者):

  • 你只需要告诉客户经理 "我要一台办公电脑",不用管具体零件和步骤;
  • 装机师傅知道所有零件搭配规则和组装顺序,会按步骤一步步装好;
  • 想换游戏电脑?换一个擅长装游戏电脑的师傅(另一个生成器)就行,你不用学新东西。

示例

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) { ...... }
//............

生成器模式让你可以分步骤生成对象, 而且允许你仅使用必须的步骤。 应用该模式后, 你再也不需要将几十个参数塞进构造函数里了。

相关推荐
铭哥的编程日记43 分钟前
《从C风格到C++风格:内存管理的进化之路》
开发语言·c++
程序员编程指南2 小时前
Qt 与 SQLite 嵌入式数据库开发
c语言·数据库·c++·qt
屁股割了还要学5 小时前
【C语言进阶】柔性数组
c语言·开发语言·数据结构·c++·学习·算法·柔性数组
oioihoii5 小时前
C++实战案例:从static成员到线程安全的单例模式
java·c++·单例模式
源代码•宸6 小时前
深入浅出设计模式——创建型模式之工厂模式
设计模式
zzzzz_ccc6 小时前
AVL树和红黑树的特性以及模拟实现
c语言·数据结构·c++
天天进步20156 小时前
设计模式在Java中的实际应用:单例、工厂与观察者模式详解
java·观察者模式·设计模式
liulilittle7 小时前
C++ Proactor 与 Reactor 网络编程模式
开发语言·网络·c++·reactor·proactor
天安彩8 小时前
mac下 vscode 运行 c++无法弹出窗口
c++·vscode·macos·clang
程序员编程指南8 小时前
Qt 网络编程进阶:WebSocket 通信
c语言·网络·c++·qt·websocket