Menu
CoddyTech

建造者模式

本课属于 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。

challenge icon

挑战

简单

让我们构建一个 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:将所有内容组合起来,构建一台自定义电脑。

    读取四项输入:

    1. CPU 型号(字符串)
    2. RAM 规格(字符串)
    3. 存储规格(字符串)
    4. 是否包含 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;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C++ 在线编译器