一、建造者模式
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);
问题点:
- 构造函数的参数太多,难以阅读和维护。
- 用户需要记住每个参数的顺序和类型,容易出错。
- 扩展性差,每次增加新属性都需要修改构造函数。
建造者模式解决方案
- 构建产品类
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;
};
- 构建建造者类
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;
};
- 构建具体建造者类
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_);
}
};
- 指挥者(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、适用场景
- 创建复杂对象:对象有很多组成部分,构造过程复杂
- 构造过程需要精细控制:需要细化构建步骤
- 对象有很多可选参数
- 需要创建不同表示的对象:同样的构建过程,不同的配置
2.3、建造者模式 VS 工厂模式
- 工厂模式:侧重于创建对象,不关心构建过程
- 建造者模式:侧重于构建过程,不关心对象类型