授课语音

建造者模式

1. 介绍

建造者模式是一种设计模式,用于构建复杂对象的各个部分,而无需指定该对象的具体类。它通过逐步创建对象的各个部分,并利用建造者对象将这些部分组装成最终产品。这种模式特别适用于需要创建复杂对象的场景,尤其是在对象的创建过程涉及多个步骤,或者对象的不同部分可以独立变化时。

主要角色

  1. 产品(Product): 最终构建的复杂对象,包含各种组成部分。
  2. 抽象建造者(Builder): 定义创建产品的步骤和方法,但不负责具体的组合。
  3. 具体建造者(Concrete Builder): 继承自抽象建造者,实现具体步骤,负责实际创建产品的部分。
  4. 指挥者(Director): 管理建造过程,调用建造者的方法以确保产品按顺序构建。
  5. 客户端(Client): 使用指挥者来获取最终产品,无需了解构建过程的细节。

应用场景

  1. 复杂对象构建: 构建需要多个步骤的复杂对象时,建造者模式非常适用。
  2. 步骤独立性: 每个步骤可能需要不同设置时,建造者模式能有效组织这些步骤。
  3. 组件独立变化: 当对象的不同部分可以独立变化时,简化对象的创建过程。
  4. 重用构建过程: 在多个地方重复使用对象的创建过程时,封装和复用逻辑。
  5. 复杂算法: 构建过程涉及复杂逻辑时,封装在具体建造者中,客户端可以简单获取产品。

优点

  1. 分离创建与表示: 提高代码灵活性和可维护性。
  2. 增加灵活性: 通过不同的建造者配置不同产品特性。
  3. 避免参数爆炸: 使代码清晰易懂。
  4. 更好的封装: 客户端专注于最终产品,无需了解创建细节。

缺点

  1. 增加复杂性: 引入多个角色可能增加系统复杂性。
  2. 多个建造者: 对于每种产品类型,可能需要定义多个具体建造者,增加代码量。

2. 代码案例

#include <iostream>
#include <string>

// =================== 产品类(Product) ===================
class Car {
private:
    std::string engine;      // 发动机类型
    std::string transmission; // 变速器类型
    std::string wheels;      // 车轮类型
    std::string color;       // 颜色
    bool isSunroof;          // 是否有天窗

public:
    Car() : isSunroof(false) {} // 默认无天窗

    std::string ToString() const {
        return "汽车 [发动机=" + engine + ", 变速器=" + transmission +
               ", 车轮=" + wheels + ", 颜色=" + color +
               ", 天窗=" + (isSunroof ? "有" : "无") + "]";
    }

    // Builder 类用于逐步构建 Car 对象。
    class Builder {
    private:
        Car car;

    public:
        Builder& SetEngine(const std::string& engine) {
            car.engine = engine;
            return *this;
        }

        Builder& SetTransmission(const std::string& transmission) {
            car.transmission = transmission;
            return *this;
        }

        Builder& SetWheels(const std::string& wheels) {
            car.wheels = wheels;
            return *this;
        }

        Builder& SetColor(const std::string& color) {
            car.color = color;
            return *this;
        }

        Builder& SetSunroof(bool isSunroof) {
            car.isSunroof = isSunroof;
            return *this;
        }

        Car Build() {
            return car;
        }
    };
};

// =================== 抽象建造者(Builder) ===================
class CarBuilder {
public:
    virtual CarBuilder& BuildEngine() = 0;
    virtual CarBuilder& BuildTransmission() = 0;
    virtual CarBuilder& BuildWheels() = 0;
    virtual CarBuilder& BuildColor() = 0;
    virtual CarBuilder& BuildSunroof() = 0;
    virtual Car Build() = 0;
    virtual ~CarBuilder() = default;
};

// =================== 具体建造者(Concrete Builder) ===================
class SportsCarBuilder : public CarBuilder {
private:
    Car::Builder builder;

public:
    CarBuilder& BuildEngine() override {
        builder.SetEngine("V8 发动机");
        return *this;
    }

    CarBuilder& BuildTransmission() override {
        builder.SetTransmission("6速手动");
        return *this;
    }

    CarBuilder& BuildWheels() override {
        builder.SetWheels("运动轮胎");
        return *this;
    }

    CarBuilder& BuildColor() override {
        builder.SetColor("红色");
        return *this;
    }

    CarBuilder& BuildSunroof() override {
        builder.SetSunroof(true);
        return *this;
    }

    Car Build() override {
        return builder.Build();
    }
};

// =================== 指挥者(Director) ===================
class CarDirector {
private:
    CarBuilder& builder;

public:
    CarDirector(CarBuilder& builder) : builder(builder) {}

    Car Construct() {
        return builder.BuildEngine()
                      .BuildTransmission()
                      .BuildWheels()
                      .BuildColor()
                      .BuildSunroof()
                      .Build();
    }
};

// =================== 客户端(Client) ===================
int main() {
    // 创建具体建造者
    SportsCarBuilder builder;

    // 创建指挥者并传入建造者
    CarDirector director(builder);

    // 使用指挥者构建汽车
    Car car = director.Construct();

    // 输出构建的汽车
    std::cout << car.ToString() << std::endl;

    // 直接使用建造者链式调用构建汽车
    Car customCar = builder.BuildEngine()
                            .BuildTransmission()
                            .BuildWheels()
                            .BuildColor()
                            .BuildSunroof()
                            .Build();
    std::cout << customCar.ToString() << std::endl;

    return 0;
}

代码详解

  1. 产品类(Car): 定义汽车的各个属性,并实现一个内部类 Builder 来支持逐步构建。
  2. 抽象建造者(CarBuilder): 定义构建汽车的各个步骤,具体实现由 SportsCarBuilder 提供。
  3. 具体建造者(SportsCarBuilder): 实现具体的构建步骤,返回 *this 以支持链式调用。
  4. 指挥者(CarDirector): 管理构建过程,确保各步骤按顺序执行。
  5. 客户端(main 函数): 演示如何通过指挥者和直接使用建造者来创建汽车,并输出结果。

这个案例清晰地展示了建造者模式的实现及应用,帮助更好地理解这一设计模式的使用场景和优势。

图示

Image___1397757895864055353===3ec0f03448b67b89573926640c0bce2e===4_1.png___

去1:1私密咨询

系列课程: