建造者模式-创建型

一、建造者模式

1.1、核心思想

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。<================>(说人话)创建步骤复杂,需要过多参数,用户只提供自己的参数,只关心最后的结果,不关心中间

的过程。比如diy主机:CPU:是考虑intel还是AMD:i5还是Rzen5 9700x等;内存是ddr5还是ddr4,选择哪个厂家,容量多大,时序多少等。

1.2、为什么需要建造者模式

问题场景

以DIY主机为例:

cpp 复制代码
// 糟糕的设计:伸缩构造函数模式
class Computer {
public:
    // 构造函数1:只有必填参数
    Computer(const string& cpu, const string& ram) 
        : cpu_(cpu), ram_(ram) {}
    
    // 构造函数2:加上可选参数
    Computer(const string& cpu, const string& ram, const string& storage) 
        : cpu_(cpu), ram_(ram), storage_(storage) {}
    
    // 构造函数3:再加上更多可选参数...
    Computer(const string& cpu, const string& ram, const string& storage, 
             const string& gpu, const string& monitor)
        : cpu_(cpu), ram_(ram), storage_(storage), gpu_(gpu), monitor_(monitor) {}
    
    // 更多构造函数...
    // 问题:参数太多,难以阅读和维护!

private:
    string cpu_;
    string ram_;
    string storage_ = "";
    string gpu_ = "";
    string monitor_ = "";
    bool bluetooth_ = false;
    // ... 更多成员
};

// 使用:哪个参数对应什么?完全看不懂!
Computer computer("i7", "16GB", "1TB SSD", "RTX 3080", "27寸4K", true, false, true);

问题点:

  1. 构造函数的参数太多,难以阅读和维护。
  2. 用户需要记住每个参数的顺序和类型,容易出错。
  3. 扩展性差,每次增加新属性都需要修改构造函数。

建造者模式解决方案

  1. 构建产品类
cpp 复制代码
// 产品类:电脑
class Computer {
public:
    // 使用友元类,让Builder可以访问私有成员
    friend class ComputerBuilder;
    
    void show() const {
        std::cout << "=== 电脑配置 ===" << std::endl;
        std::cout << "CPU: " << cpu_ << std::endl;
        std::cout << "内存: " << ram_ << std::endl;
        if (!storage_.empty()) {
            std::cout << "存储: " << storage_ << std::endl;
        }
        if (!gpu_.empty()) {
            std::cout << "显卡: " << gpu_ << std::endl;
        }
        if (!monitor_.empty()) {
            std::cout << "显示器: " << monitor_ << std::endl;
        }
        std::cout << "蓝牙: " << (bluetooth_ ? "支持" : "不支持") << std::endl;
        std::cout << "WiFi: " << (wifi_ ? "支持" : "不支持") << std::endl;
        std::cout << "总价: ¥" << price_ << std::endl;
    }

private:
    // 私有构造函数,只能通过Builder创建
    Computer() = default;
    
    // 电脑组件
    std::string cpu_;
    std::string ram_;
    std::string storage_;
    std::string gpu_;
    std::string monitor_;
    bool bluetooth_ = false;
    bool wifi_ = false;
    double price_ = 0.0;
};
  1. 构建建造者类
cpp 复制代码
// 抽象建造者
class ComputerBuilder {
public:
    virtual ~ComputerBuilder() = default;
    
    // 构建步骤
    virtual void buildCPU(const std::string& cpu) = 0;
    virtual void buildRAM(const std::string& ram) = 0;
    virtual void buildStorage(const std::string& storage) = 0;
    virtual void buildGPU(const std::string& gpu) = 0;
    virtual void buildMonitor(const std::string& monitor) = 0;
    virtual void buildBluetooth(bool enabled) = 0;
    virtual void buildWifi(bool enabled) = 0;
    
    // 获取产品
    virtual std::unique_ptr<Computer> getResult() = 0;
};
  1. 构建具体建造者类
cpp 复制代码
// 具体建造者:游戏电脑建造者
class GamingComputerBuilder : public ComputerBuilder {
private:
    std::unique_ptr<Computer> computer_;
    
public:
    GamingComputerBuilder() {
        computer_ = std::make_unique<Computer>();
        computer_->price_ = 0.0; // 初始价格
    }
    
    void buildCPU(const std::string& cpu) override {
        computer_->cpu_ = cpu;
        computer_->price_ += (cpu.find("i9") != std::string::npos) ? 3500 : 2500;
        std::cout << "安装CPU: " << cpu << std::endl;
    }
    
    void buildRAM(const std::string& ram) override {
        computer_->ram_ = ram;
        computer_->price_ += (ram.find("32GB") != std::string::npos) ? 1200 : 800;
        std::cout << "安装内存: " << ram << std::endl;
    }
    
    void buildStorage(const std::string& storage) override {
        computer_->storage_ = storage;
        computer_->price_ += (storage.find("2TB") != std::string::npos) ? 1500 : 800;
        std::cout << "安装存储: " << storage << std::endl;
    }
    
    void buildGPU(const std::string& gpu) override {
        computer_->gpu_ = gpu;
        computer_->price_ += (gpu.find("RTX") != std::string::npos) ? 5000 : 2000;
        std::cout << "安装显卡: " << gpu << std::endl;
    }
    
    void buildMonitor(const std::string& monitor) override {
        computer_->monitor_ = monitor;
        computer_->price_ += (monitor.find("4K") != std::string::npos) ? 2000 : 1000;
        std::cout << "连接显示器: " << monitor << std::endl;
    }
    
    void buildBluetooth(bool enabled) override {
        computer_->bluetooth_ = enabled;
        computer_->price_ += enabled ? 100 : 0;
        std::cout << "配置蓝牙: " << (enabled ? "支持" : "不支持") << std::endl;
    }
    
    void buildWifi(bool enabled) override {
        computer_->wifi_ = enabled;
        computer_->price_ += enabled ? 150 : 0;
        std::cout << "配置WiFi: " << (enabled ? "支持" : "不支持") << std::endl;
    }
    
    std::unique_ptr<Computer> getResult() override {
        std::cout << "游戏电脑组装完成!" << std::endl;
        return std::move(computer_);
    }
};

// 具体建造者:办公电脑建造者
class OfficeComputerBuilder : public ComputerBuilder {
private:
    std::unique_ptr<Computer> computer_;
    
public:
    OfficeComputerBuilder() {
        computer_ = std::make_unique<Computer>();
        computer_->price_ = 0.0;
    }
    
    void buildCPU(const std::string& cpu) override {
        computer_->cpu_ = cpu;
        computer_->price_ += (cpu.find("i5") != std::string::npos) ? 1200 : 800;
        std::cout << "安装CPU: " << cpu << std::endl;
    }
    
    void buildRAM(const std::string& ram) override {
        computer_->ram_ = ram;
        computer_->price_ += 400; // 办公电脑内存价格固定
        std::cout << "安装内存: " << ram << std::endl;
    }
    
    void buildStorage(const std::string& storage) override {
        computer_->storage_ = storage;
        computer_->price_ += 500;
        std::cout << "安装存储: " << storage << std::endl;
    }
    
    void buildGPU(const std::string& gpu) override {
        // 办公电脑默认集成显卡
        if (!gpu.empty()) {
            computer_->gpu_ = gpu;
            computer_->price_ += 800;
            std::cout << "安装显卡: " << gpu << std::endl;
        }
    }
    
    void buildMonitor(const std::string& monitor) override {
        computer_->monitor_ = monitor;
        computer_->price_ += 800;
        std::cout << "连接显示器: " << monitor << std::endl;
    }
    
    void buildBluetooth(bool enabled) override {
        computer_->bluetooth_ = enabled;
        computer_->price_ += enabled ? 50 : 0;
        std::cout << "配置蓝牙: " << (enabled ? "支持" : "不支持") << std::endl;
    }
    
    void buildWifi(bool enabled) override {
        computer_->wifi_ = enabled;
        computer_->price_ += enabled ? 80 : 0;
        std::cout << "配置WiFi: " << (enabled ? "支持" : "不支持") << std::endl;
    }
    
    std::unique_ptr<Computer> getResult() override {
        std::cout << "办公电脑组装完成!" << std::endl;
        return std::move(computer_);
    }
};
  1. 指挥者(Director):指导构建过程,但不直接参与具体建造细节。
cpp 复制代码
// 指挥者:指导构建过程
class ComputerDirector {
public:
    void constructGamingComputer(ComputerBuilder& builder) {
        std::cout << "\n开始构建高性能游戏电脑..." << std::endl;
        builder.buildCPU("Intel i9-13900K");
        builder.buildRAM("32GB DDR5");
        builder.buildStorage("2TB NVMe SSD");
        builder.buildGPU("NVIDIA RTX 4080");
        builder.buildMonitor("32寸4K 144Hz");
        builder.buildBluetooth(true);
        builder.buildWifi(true);
    }
    
    void constructOfficeComputer(ComputerBuilder& builder) {
        std::cout << "\n开始构建办公电脑..." << std::endl;
        builder.buildCPU("Intel i5-12400");
        builder.buildRAM("16GB DDR4");
        builder.buildStorage("512GB SSD");
        builder.buildGPU(""); // 集成显卡
        builder.buildMonitor("24寸1080P");
        builder.buildBluetooth(true);
        builder.buildWifi(true);
    }
    
    void constructBasicComputer(ComputerBuilder& builder) {
        std::cout << "\n开始构建基础电脑..." << std::endl;
        builder.buildCPU("Intel i3-12100");
        builder.buildRAM("8GB DDR4");
        builder.buildStorage("256GB SSD");
        builder.buildMonitor("21.5寸1080P");
        // 不调用 buildGPU, buildBluetooth, buildWifi 使用默认值
    }
};

// 使用示例
void demoBuilderPattern() {
    std::cout << "=== 建造者模式演示 ===" << std::endl;
    
    ComputerDirector director;
    
    // 构建游戏电脑
    GamingComputerBuilder gamingBuilder;
    director.constructGamingComputer(gamingBuilder);
    auto gamingPC = gamingBuilder.getResult();
    gamingPC->show();
    
    // 构建办公电脑
    OfficeComputerBuilder officeBuilder;
    director.constructOfficeComputer(officeBuilder);
    auto officePC = officeBuilder.getResult();
    officePC->show();
    
    // 自定义构建
    std::cout << "\n=== 自定义构建 ===" << std::endl;
    GamingComputerBuilder customBuilder;
    customBuilder.buildCPU("AMD Ryzen 7 7800X3D");
    customBuilder.buildRAM("64GB DDR5");
    customBuilder.buildStorage("4TB NVMe SSD");
    customBuilder.buildGPU("AMD RX 7900 XTX");
    customBuilder.buildMonitor("34寸曲面带鱼屏");
    customBuilder.buildBluetooth(true);
    customBuilder.buildWifi(true);
    
    auto customPC = customBuilder.getResult();
    customPC->show();
}

1.3、建造者模式常见的四个角色

  • Product(产品角色):一个具体的产品对象,比如上面的Computer
  • Builder(抽象建造者):定义构建步骤的接口,比如上面的ComputerBuilder
  • ConcreteBuilder(具体建造者):实现构建步骤,比如上面的GamingComputerBuilder, OfficeComputerBuilder
  • Director(指挥者):指导构建过程以及隔离客户与对象的生产过程,比如上面的ComputerDirector

附上UML类图:

二、总结

2.1、优缺点

优点 缺点
构造过程清晰可控 增加了代码复杂度
避免伸缩构造函数 需要创建多个类
可以分布构建对象 适合复杂对象,简单对象不划算
更好的参数验证 产品类需要暴露给建造者

2.2、适用场景

  1. 创建复杂对象:对象有很多组成部分,构造过程复杂
  2. 构造过程需要精细控制:需要细化构建步骤
  3. 对象有很多可选参数
  4. 需要创建不同表示的对象:同样的构建过程,不同的配置

2.3、建造者模式 VS 工厂模式

  • 工厂模式:侧重于创建对象,不关心构建过程
  • 建造者模式:侧重于构建过程,不关心对象类型
相关推荐
ZouZou老师8 天前
C++设计模式之建造者模式:以电脑组装为例
c++·设计模式·建造者模式
雨中飘荡的记忆14 天前
设计模式之建造者模式详解
java·设计模式·建造者模式
雨中飘荡的记忆14 天前
StepBuilder模式详解
java·建造者模式
__万波__16 天前
二十三种设计模式(五)--建造者模式
java·设计模式·建造者模式
沐浴露z17 天前
为什么使用SpringAI时通常用Builder来创建对象?详解 【Builder模式】和【直接 new】的区别
java·python·建造者模式
口袋物联21 天前
设计模式之建造者模式在 C 语言中的应用(含 Linux 内核实例)
c语言·设计模式·建造者模式
phdsky22 天前
【设计模式】建造者模式
c++·设计模式·建造者模式
曹绍华1 个月前
okhttp建造者模式详解
okhttp·建造者模式
ZHE|张恒1 个月前
设计模式(四)建造者模式 — 分步骤构建复杂对象,让创建过程可控可扩展
设计模式·建造者模式