建造者模式
本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 93 课,共 104 课。
构建器模式将复杂对象的构建过程与其表示分离,让你可以逐步创建不同的配置。当对象有许多可选参数或需要按照特定顺序构建时,这种模式尤其有用。
与参数很多(容易让人困惑)的构造函数不同,Builder 为每个配置选项提供了清晰、命名明确的方法:
#include <iostream>
#include <string>
class Pizza {
public:
std::string dough;
std::string sauce;
std::string topping;
bool cheese;
void describe() const {
std::cout << dough << " dough, " << sauce << " sauce, "
<< topping << (cheese ? ", with cheese" : "") << "\n";
}
};
class PizzaBuilder {
private:
Pizza pizza;
public:
PizzaBuilder& setDough(const std::string& d) {
pizza.dough = d;
return *this;
}
PizzaBuilder& setSauce(const std::string& s) {
pizza.sauce = s;
return *this;
}
PizzaBuilder& setTopping(const std::string& t) {
pizza.topping = t;
return *this;
}
PizzaBuilder& addCheese() {
pizza.cheese = true;
return *this;
}
Pizza build() { return pizza; }
};
int main() {
Pizza margherita = PizzaBuilder()
.setDough("thin")
.setSauce("tomato")
.setTopping("basil")
.addCheese()
.build();
margherita.describe();
}每个设置方法都会返回构建器的引用(return *this),从而支持方法链式调用,实现流畅接口。build() 方法会完成构建并返回构造好的对象。
当你要构建包含许多可选组件的对象、希望构建代码易于阅读,或同一构建过程需要创建不同表示形式时,可以使用 Builder。
挑战
简单让我们构建一个 Computer Builder 系统,让用户逐步配置自定义电脑。这是使用 Builder 模式的绝佳场景:电脑有许多可选组件,而我们希望用一种简洁易读的方式来组装不同配置。
你会将代码分布在三个文件中:
Computer.h:定义产品类,用来表示一台配置完整的电脑。你的
Computer类应将以下组件作为私有成员保存:cpu(字符串)、ram(字符串)、storage(字符串)、gpu(字符串)和hasWifi(布尔值)。将hasWifi初始化为false,并默认将字符串初始化为空。添加一个名为
showSpecs()的公共方法,用来显示电脑配置。对于每个已设置的组件(非空字符串),单独打印一行。只有启用了 wifi 功能时,才打印该功能。ComputerBuilder.h:创建 Builder 类,通过流式接口构建电脑。你的
ComputerBuilder类应包含一个私有的Computer成员,用来逐步构建电脑。实现以下方法,每个方法都返回 Builder 的引用,以支持方法链式调用:setCPU(const std::string& cpu)setRAM(const std::string& ram)setStorage(const std::string& storage)setGPU(const std::string& gpu)addWifi():启用 wifi 功能
另外,实现一个
build()方法,返回构建完成的Computer对象,并重置 Builder,以便之后再次使用。main.cpp:将所有内容组合起来,构建一台自定义电脑。读取四项输入:
- CPU 型号(字符串)
- RAM 规格(字符串)
- 存储规格(字符串)
- 是否包含 wifi:
yes或no
使用
ComputerBuilder,根据提供的 CPU、RAM 和存储信息构建电脑。如果 wifi 输入为yes,还要调用addWifi()。注意,这项配置没有指定 GPU:Builder 应能妥善处理可选组件。构建完成后,在生成的电脑上调用
showSpecs(),显示其配置。
showSpecs() 方法应按以下格式输出(只显示已设置的组件):
CPU: [value]
RAM: [value]
Storage: [value]
GPU: [value]
Wifi: Enabled例如,输入 Intel i7-12700K、32GB DDR5、1TB NVMe SSD 和 yes 时:
CPU: Intel i7-12700K
RAM: 32GB DDR5
Storage: 1TB NVMe SSD
Wifi: Enabled输入 AMD Ryzen 5 5600X、16GB DDR4、512GB SSD 和 no 时:
CPU: AMD Ryzen 5 5600X
RAM: 16GB DDR4
Storage: 512GB SSD注意,Builder 模式让构建过程变得清晰灵活。你可以轻松添加或跳过组件,方法链式调用也让代码一目了然,并能清楚地说明代码用途。由于我们没有设置 GPU,因此不会显示 GPU 这一行,这也展示了 Builder 如何自然地处理可选组件。
亲手试试
#include <iostream>
#include <string>
#include "ComputerBuilder.h"
using namespace std;
int main() {
// 读取输入
string cpu, ram, storage, wifiChoice;
getline(cin, cpu);
getline(cin, ram);
getline(cin, storage);
getline(cin, wifiChoice);
// TODO: 创建一个 ComputerBuilder 实例
// TODO: 使用方法链设置 CPU、RAM 和存储空间
// TODO: 如果 wifiChoice 是 "yes",还要调用 addWifi()
// TODO: 调用 build() 获取 Computer 对象
// TODO: 对构建好的计算机调用 showSpecs(),显示配置
return 0;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C++ 在线编译器