设计模式 | 建造者模式
建造者模式(Builder Pattern) 是创建型设计模式中的精妙之作,它将复杂对象的构造过程与其表示方式分离,使得同样的构建过程可以创建不同的表示。本文将深入探索建造者模式的核心思想、实现技巧以及在C++中的高效实践。
为什么需要建造者模式?
在软件开发中,我们经常遇到需要创建复杂对象的场景:
-
包含多个组成部分的对象
-
需要分步骤构造的对象
-
构造过程需要不同表示的对象
-
需要避免"重叠构造函数"(telescoping constructor)反模式
直接使用构造函数或工厂方法会导致:
-
构造函数参数过多且难以理解
-
构造过程与对象表示紧耦合
-
无法控制构造步骤
-
难以创建对象的不同变体
建造者模式通过分离构造算法与对象表示解决了这些问题。
建造者模式的核心概念
[导演] → [建造者接口]↑[具体建造者] → [产品]
关键角色定义
-
产品(Product)
-
最终要构建的复杂对象
-
-
抽象建造者(Builder)
-
定义创建产品各部分的接口
-
-
具体建造者(Concrete Builder)
-
实现抽象建造者接口
-
提供产品的具体实现
-
保存产品的当前状态
-
-
导演(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();
建造者模式的适用场景
-
复杂对象创建
// 创建包含多个子系统的游戏角色 CharacterBuilder().setAppearance("Elf").setSkills({"Archery", "Stealth"}).setEquipment("Longbow", "Leather Armor").setAttributes({strength: 12, dexterity: 18}).build();
-
配置对象构建
// 构建复杂配置对象 Config config = ConfigBuilder().setDatabase("MySQL", "localhost", 3306).setLogging(true, "debug.log").setNetworkTimeout(5000).setSecurity(true, true).build();
-
文档转换器
// 构建不同格式的文档 DocumentBuilder& builder = getFormatBuilder("PDF"); director.buildDocument(builder, content); Document doc = builder.getResult();
-
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();
最佳实践与注意事项
-
避免过度设计
-
当对象简单时,直接使用构造函数
-
建造者模式适用于至少4个参数的复杂对象
-
-
保持建造者接口简洁
// 良好的接口设计 class CarBuilder { public:CarBuilder& setEngine(const Engine& engine);CarBuilder& addWheel(const Wheel& wheel);CarBuilder& setColor(Color color);Car build(); };
-
处理可选参数
// 使用默认值处理可选参数 class PizzaBuilder { public:PizzaBuilder& setCheese(bool hasCheese = true) {pizza.hasCheese = hasCheese;return *this;} };
-
保证构建完整性
// 在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); }
总结
建造者模式通过以下方式彻底改变了复杂对象的创建过程:
-
分离构造与表示:相同的构建过程创建不同表示
-
精细控制:精确控制对象构建步骤
-
简化接口:避免复杂的构造函数参数列表
-
构建算法复用:导演类封装复杂构建逻辑
-
参数验证:在build()方法中确保对象完整性
使用时机:
-
当对象需要多个步骤创建时
-
当对象有多个变体时
-
当需要隔离复杂对象的创建和使用时
-
当构造过程需要不同的表示时
"建造者模式不是简单地创建对象,而是精心策划对象的诞生过程。它是面向对象设计中构造复杂对象的优雅解决方案。" - 设计模式实践者