当前位置: 首页 > news >正文

设计模式 | 建造者模式

建造者模式(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()方法中确保对象完整性

使用时机

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

  • 当对象有多个变体时

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

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

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

http://www.lqws.cn/news/531037.html

相关文章:

  • 【机器学习深度学习】线性代数
  • 提升开发思维的设计模式(下)
  • Apache 支持 HTTPS
  • 【Linux】软硬链接,动静态库
  • 流程管理整体章程性方案及流程中的各种操作的定义和说明
  • 2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷(四)
  • 【机器学习深度学习】线性回归
  • SpringBoot 中使用 @Async 实现异步调用​
  • 详解零拷贝
  • IDEA + Spring Boot + javadoc 实例应用
  • MyBatis深度面试指南
  • MQTT 和 HTTP 有什么本质区别?
  • Lynx vs React Native vs Flutter 全面对比:三大跨端框架实测分析
  • flutter的包管理#资源管理#调试Flutter应用#Flutter异常捕获
  • OpenCV边缘填充方式详解
  • ffmpeg中Avfilter组件drawbox和drawgrid的bug
  • 远程面试平台选声网视频通话提升候选人体验感
  • 编写CSS的格式
  • 2025学年湖北省职业院校技能大赛 “信息安全管理与评估”赛项 样题卷(五)
  • 【STM32】外部中断
  • HTTP协议-后端接收请求
  • CRON表达式编辑器与定时任务实现技术文档
  • Sonarqube:Jenkins触发sonar扫描出现UnsupportedClassVersionError错误处理
  • EXILIUM×亚矩云手机:重构Web3虚拟生存法则,开启多端跨链元宇宙自由征途
  • GEO引领品牌大模型种草:迈向Web3.0与元宇宙的认知新空间
  • 【算法深练】栈特性的解题密码:LIFO规则在题型中的灵活运用
  • 供应链管理:计划相关岗位及其岗位职责
  • 【C++】ATM机模拟系统 :完整窗口实现
  • 机器学习15-规则学习-知识加强
  • MySQL-主从复制分库分表