设计模式 | 建造者模式

发布于:2025-06-28 ⋅ 阅读:(14) ⋅ 点赞:(0)

建造者模式(Builder Pattern) 是创建型设计模式中的精妙之作,它将复杂对象的构造过程与其表示方式分离,使得同样的构建过程可以创建不同的表示。本文将深入探索建造者模式的核心思想、实现技巧以及在C++中的高效实践。

为什么需要建造者模式?

在软件开发中,我们经常遇到需要创建复杂对象的场景:

  • 包含多个组成部分的对象

  • 需要分步骤构造的对象

  • 构造过程需要不同表示的对象

  • 需要避免"重叠构造函数"(telescoping constructor)反模式

直接使用构造函数或工厂方法会导致:

  • 构造函数参数过多且难以理解

  • 构造过程与对象表示紧耦合

  • 无法控制构造步骤

  • 难以创建对象的不同变体

建造者模式通过分离构造算法与对象表示解决了这些问题。

建造者模式的核心概念

[导演] → [建造者接口]
              ↑
        [具体建造者] → [产品]

关键角色定义

  1. 产品(Product)

    • 最终要构建的复杂对象

  2. 抽象建造者(Builder)

    • 定义创建产品各部分的接口

  3. 具体建造者(Concrete Builder)

    • 实现抽象建造者接口

    • 提供产品的具体实现

    • 保存产品的当前状态

  4. 导演(Director)

    • 使用建造者接口构建产品

    • 控制构建过程顺序

C++实现:定制化电脑配置系统

让我们实现一个电脑定制系统,用户可以按需选择不同组件:

#include <iostream>
#include <memory>
#include <string>
#include <vector>

// ================= 产品类:Computer =================
class Computer {
public:
    void setCPU(const std::string& cpu) { cpu_ = cpu; }
    void setRAM(const std::string& ram) { ram_ = ram; }
    void setStorage(const std::string& storage) { storage_ = storage; }
    void setGPU(const std::string& gpu) { gpu_ = gpu; }
    void addPeripheral(const std::string& peripheral) {
        peripherals_.push_back(peripheral);
    }

    void display() const {
        std::cout << "电脑配置详情:\n";
        std::cout << "---------------------------------\n";
        std::cout << "CPU: " << cpu_ << "\n";
        std::cout << "RAM: " << ram_ << "\n";
        std::cout << "存储: " << storage_ << "\n";
        if (!gpu_.empty()) std::cout << "显卡: " << gpu_ << "\n";
        
        if (!peripherals_.empty()) {
            std::cout << "外设:\n";
            for (const auto& p : peripherals_) {
                std::cout << "  - " << p << "\n";
            }
        }
        std::cout << "=================================\n\n";
    }

private:
    std::string cpu_;
    std::string ram_;
    std::string storage_;
    std::string gpu_; // 可选
    std::vector<std::string> peripherals_;
};

// ================= 抽象建造者 =================
class ComputerBuilder {
public:
    virtual ~ComputerBuilder() = default;
    
    virtual void buildCPU() = 0;
    virtual void buildRAM() = 0;
    virtual void buildStorage() = 0;
    virtual void buildGPU() = 0; // 可选步骤
    virtual void buildPeripherals() = 0; // 可选步骤
    
    Computer getResult() { 
        return std::move(computer_); 
    }

protected:
    Computer computer_;
};

// ================= 具体建造者:游戏电脑 =================
class GamingComputerBuilder : public ComputerBuilder {
public:
    void buildCPU() override {
        computer_.setCPU("Intel Core i9-13900K");
    }
    
    void buildRAM() override {
        computer_.setRAM("32GB DDR5 6000MHz");
    }
    
    void buildStorage() override {
        computer_.setStorage("2TB NVMe SSD");
    }
    
    void buildGPU() override {
        computer_.setGPU("NVIDIA RTX 4090");
    }
    
    void buildPeripherals() override {
        computer_.addPeripheral("机械键盘");
        computer_.addPeripheral("游戏鼠标");
        computer_.addPeripheral("27寸 240Hz显示器");
    }
};

// ================= 具体建造者:办公电脑 =================
class OfficeComputerBuilder : public ComputerBuilder {
public:
    void buildCPU() override {
        computer_.setCPU("Intel Core i5-13400");
    }
    
    void buildRAM() override {
        computer_.setRAM("16GB DDR4 3200MHz");
    }
    
    void buildStorage() override {
        computer_.setStorage("512GB SSD + 1TB HDD");
    }
    
    // 办公电脑不需要独立显卡
    void buildGPU() override {}
    
    void buildPeripherals() override {
        computer_.addPeripheral("标准键盘");
        computer_.addPeripheral("办公鼠标");
        computer_.addPeripheral("24寸显示器");
    }
};

// ================= 具体建造者:自定义电脑 =================
class CustomComputerBuilder : public ComputerBuilder {
public:
    CustomComputerBuilder& setCPUModel(const std::string& model) {
        cpuModel_ = model;
        return *this;
    }
    
    CustomComputerBuilder& setRAMSize(const std::string& size) {
        ramSize_ = size;
        return *this;
    }
    
    // 其他自定义设置方法...
    
    void buildCPU() override {
        computer_.setCPU(cpuModel_.empty() ? "AMD Ryzen 5 7600" : cpuModel_);
    }
    
    void buildRAM() override {
        computer_.setRAM(ramSize_.empty() ? "16GB DDR5" : ramSize_);
    }
    
    void buildStorage() override {
        computer_.setStorage("1TB NVMe SSD");
    }
    
    void buildGPU() override {
        computer_.setGPU("集成显卡");
    }
    
    void buildPeripherals() override {
        // 自定义电脑默认不带外设
    }

private:
    std::string cpuModel_;
    std::string ramSize_;
};

// ================= 导演类 =================
class ComputerDirector {
public:
    void setBuilder(ComputerBuilder* builder) {
        builder_ = builder;
    }
    
    void constructBasicComputer() {
        builder_->buildCPU();
        builder_->buildRAM();
        builder_->buildStorage();
    }
    
    void constructFullComputer() {
        constructBasicComputer();
        builder_->buildGPU();
        builder_->buildPeripherals();
    }
    
    Computer getComputer() {
        return builder_->getResult();
    }

private:
    ComputerBuilder* builder_;
};

// ================= 客户端代码 =================
int main() {
    ComputerDirector director;
    
    // 构建游戏电脑
    GamingComputerBuilder gamingBuilder;
    director.setBuilder(&gamingBuilder);
    director.constructFullComputer();
    Computer gamingPC = director.getComputer();
    gamingPC.display();
    
    // 构建办公电脑
    OfficeComputerBuilder officeBuilder;
    director.setBuilder(&officeBuilder);
    director.constructBasicComputer(); // 办公电脑不需要外设
    Computer officePC = director.getComputer();
    officePC.display();
    
    // 构建自定义电脑
    CustomComputerBuilder customBuilder;
    customBuilder.setCPUModel("AMD Ryzen 9 7950X")
                 .setRAMSize("64GB DDR5 6000MHz");
    
    director.setBuilder(&customBuilder);
    director.constructFullComputer();
    Computer customPC = director.getComputer();
    customPC.display();
    
    return 0;
}

建造者模式的核心优势

1. 分步构建复杂对象

// 导演控制构建步骤
void constructCar() {
    builder->buildFrame();
    builder->buildEngine();
    builder->buildWheels();
    builder->buildElectronics();
}

2. 灵活创建不同表示

// 使用不同建造者创建不同产品
ElectricCarBuilder electricBuilder;
director.setBuilder(&electricBuilder);
director.constructCar();

CombustionCarBuilder combustionBuilder;
director.setBuilder(&combustionBuilder);
director.constructCar();

3. 避免重叠构造函数

// 传统方式 - 难以理解和维护
Computer(
    "i9", "32GB", "2TB SSD", "RTX4090", 
    "机械键盘", "游戏鼠标", "240Hz显示器"
);

// 建造者方式 - 清晰明了
ComputerBuilder()
    .setCPU("i9")
    .setRAM("32GB")
    .setStorage("2TB SSD")
    .setGPU("RTX4090")
    .addPeripheral("机械键盘")
    .addPeripheral("游戏鼠标")
    .addPeripheral("240Hz显示器")
    .build();

4. 精细控制构建过程

// 可选的构建步骤
if (needsHighPerformance) {
    builder->buildHighEndGPU();
} else {
    builder->buildIntegratedGPU();
}

建造者模式的高级应用

1. 流式接口(Fluent Interface)

class PizzaBuilder {
public:
    PizzaBuilder& setSize(const std::string& size) {
        pizza_.size = size;
        return *this;
    }
    
    PizzaBuilder& addTopping(const std::string& topping) {
        pizza_.toppings.push_back(topping);
        return *this;
    }
    
    PizzaBuilder& setCrust(const std::string& crust) {
        pizza_.crust = crust;
        return *this;
    }
    
    Pizza build() {
        return std::move(pizza_);
    }

private:
    Pizza pizza_;
};

// 使用示例
Pizza pizza = PizzaBuilder()
    .setSize("Large")
    .setCrust("Thin")
    .addTopping("Pepperoni")
    .addTopping("Mushrooms")
    .addTopping("Extra Cheese")
    .build();

2. 复合对象构建

class HouseBuilder {
public:
    virtual void buildFoundation() = 0;
    virtual void buildStructure() = 0;
    virtual void buildRoof() = 0;
    virtual void buildInterior() = 0;
    virtual House getResult() = 0;
};

class House {
private:
    std::vector<Room> rooms;
    std::vector<Door> doors;
    std::vector<Window> windows;
    // 允许建造者访问私有成员
    friend class HouseBuilderImpl;
};

class HouseBuilderImpl : public HouseBuilder {
public:
    void buildFoundation() override {
        house_.foundation = Foundation("Concrete");
    }
    
    void buildStructure() override {
        house_.structure = Structure("Wooden Frame");
    }
    
    // ...其他实现
    
    House getResult() override {
        return std::move(house_);
    }

private:
    House house_;
};

3. 与工厂模式结合

class ComputerFactory {
public:
    static Computer createGamingComputer() {
        GamingComputerBuilder builder;
        ComputerDirector director;
        director.setBuilder(&builder);
        director.constructFullComputer();
        return director.getComputer();
    }
    
    static Computer createOfficeComputer() {
        OfficeComputerBuilder builder;
        ComputerDirector director;
        director.setBuilder(&builder);
        director.constructBasicComputer();
        return director.getComputer();
    }
    
    static Computer createCustomComputer(
        const std::string& cpu, 
        const std::string& ram, 
        const std::string& storage
    ) {
        CustomComputerBuilder builder;
        builder.setCPU(cpu)
               .setRAM(ram)
               .setStorage(storage);
        
        ComputerDirector director;
        director.setBuilder(&builder);
        director.constructBasicComputer();
        return director.getComputer();
    }
};

建造者模式的变体

1. 静态建造者(使用CRTP)

template <typename T>
class StaticBuilder {
protected:
    T& self() { return static_cast<T&>(*this); }
    
public:
    operator T() {
        return static_cast<T&&>(*this);
    }
};

class Car : public StaticBuilder<Car> {
public:
    Car& setModel(const std::string& model) {
        model_ = model;
        return self();
    }
    
    Car& setColor(const std::string& color) {
        color_ = color;
        return self();
    }
    
private:
    std::string model_;
    std::string color_;
};

// 使用
Car myCar = Car().setModel("Model S").setColor("Red");

2. 无导演的建造者模式

class ComputerAssembler {
public:
    ComputerAssembler(ComputerBuilder& builder) 
        : builder_(builder) {}
    
    void assemble() {
        builder_.buildCPU();
        builder_.buildRAM();
        builder_.buildStorage();
        
        if (needsGPU_) {
            builder_.buildGPU();
        }
    }
    
    ComputerAssembler& withGPU(bool needsGPU) {
        needsGPU_ = needsGPU;
        return *this;
    }
    
    Computer getResult() {
        return builder_.getResult();
    }

private:
    ComputerBuilder& builder_;
    bool needsGPU_ = false;
};

// 使用
GamingComputerBuilder builder;
ComputerAssembler assembler(builder);
Computer pc = assembler.withGPU(true).assemble().getResult();

建造者模式的适用场景

  1. 复杂对象创建

    // 创建包含多个子系统的游戏角色
    CharacterBuilder()
        .setAppearance("Elf")
        .setSkills({"Archery", "Stealth"})
        .setEquipment("Longbow", "Leather Armor")
        .setAttributes({strength: 12, dexterity: 18})
        .build();
  2. 配置对象构建

    // 构建复杂配置对象
    Config config = ConfigBuilder()
        .setDatabase("MySQL", "localhost", 3306)
        .setLogging(true, "debug.log")
        .setNetworkTimeout(5000)
        .setSecurity(true, true)
        .build();
  3. 文档转换器

    // 构建不同格式的文档
    DocumentBuilder& builder = getFormatBuilder("PDF");
    director.buildDocument(builder, content);
    Document doc = builder.getResult();
  4. SQL查询构建器

    // 构建复杂SQL查询
    Query query = QueryBuilder()
        .select("id", "name", "email")
        .from("users")
        .where("age > 18")
        .orderBy("name")
        .limit(100)
        .build();

与其他创建型模式的对比

模式 目的 复杂度 灵活性
建造者模式 分步创建复杂对象
工厂模式 创建单一类型对象
抽象工厂 创建产品家族
原型模式 克隆现有对象

组合使用示例

// 抽象工厂 + 建造者
class UIFactory {
public:
    virtual ButtonBuilder createButtonBuilder() = 0;
    virtual WindowBuilder createWindowBuilder() = 0;
};

class WindowsUIFactory : public UIFactory {
public:
    ButtonBuilder createButtonBuilder() override {
        return WindowsButtonBuilder();
    }
    
    WindowBuilder createWindowBuilder() override {
        return WindowsWindowBuilder();
    }
};

// 使用
auto builder = factory.createButtonBuilder();
Button button = builder.setText("OK")
                   .setSize(100, 50)
                   .setColor(COLOR_BLUE)
                   .build();

最佳实践与注意事项

  1. 避免过度设计

    • 当对象简单时,直接使用构造函数

    • 建造者模式适用于至少4个参数的复杂对象

  2. 保持建造者接口简洁

    // 良好的接口设计
    class CarBuilder {
    public:
        CarBuilder& setEngine(const Engine& engine);
        CarBuilder& addWheel(const Wheel& wheel);
        CarBuilder& setColor(Color color);
        Car build();
    };
  3. 处理可选参数

    // 使用默认值处理可选参数
    class PizzaBuilder {
    public:
        PizzaBuilder& setCheese(bool hasCheese = true) {
            pizza.hasCheese = hasCheese;
            return *this;
        }
    };
  4. 保证构建完整性

    // 在build()方法中验证参数
    Car CarBuilder::build() {
        if (wheels.size() != 4) {
            throw std::runtime_error("汽车必须有4个轮子");
        }
        if (engine.type.empty()) {
            throw std::runtime_error("未设置引擎");
        }
        return std::move(car);
    }

总结

建造者模式通过以下方式彻底改变了复杂对象的创建过程:

  1. 分离构造与表示:相同的构建过程创建不同表示

  2. 精细控制:精确控制对象构建步骤

  3. 简化接口:避免复杂的构造函数参数列表

  4. 构建算法复用:导演类封装复杂构建逻辑

  5. 参数验证:在build()方法中确保对象完整性

使用时机

  • 当对象需要多个步骤创建时

  • 当对象有多个变体时

  • 当需要隔离复杂对象的创建和使用时

  • 当构造过程需要不同的表示时

"建造者模式不是简单地创建对象,而是精心策划对象的诞生过程。它是面向对象设计中构造复杂对象的优雅解决方案。" - 设计模式实践者