C++设计模式-Builder 构建器

2023-12-14 13:44:26

通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。

一、动机

  • 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定

  • 如何应对这种变化?如何提供一种 “封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?

二、模式定义

将一个复杂对象的构建与其表示相分离,使得同样的构建过
程(稳定)可以创建不同的表示(变化)。
——《设计模式》GoF

三、代码示例

我们以房屋为例来展示建造者模式的应用。House类代表房屋对象,而HouseBuilder抽象类定义了构建房屋的步骤。StoneHouseBuilderHouseBuilder的具体实现,用于构建石头房屋。HouseDirector类负责指导具体建造者对象的构建过程。

通过使用建造者模式,我们可以将房屋对象的构建逻辑与客户端代码分离开来。客户端只需要创建一个合适的具体建造者对象,并将其传递给指导者进行构建。这样可以使客户端代码更简洁、可读性更高,并且在需要构建不同类型的房屋时更加灵活和扩展。

#include <iostream>

class House {
public:
    void SetFoundation(const std::string& foundation) {
        this->foundation = foundation;
    }

    void SetWalls(const std::string& walls) {
        this->walls = walls;
    }

    void SetRoof(const std::string& roof) {
        this->roof = roof;
    }

    void SetDoors(const std::string& doors) {
        this->doors = doors;
    }

    void SetWindows(const std::string& windows) {
        this->windows = windows;
    }

    void Show() {
        std::cout << "房屋部分:" << std::endl;
        std::cout << "地基:" << foundation << std::endl;
        std::cout << "墙壁:" << walls << std::endl;
        std::cout << "屋顶:" << roof << std::endl;
        std::cout << "门:" << doors << std::endl;
        std::cout << "窗户:" << windows << std::endl;
    }

private:
    std::string foundation;  // 地基
    std::string walls;       // 墙壁
    std::string roof;        // 屋顶
    std::string doors;       // 门
    std::string windows;     // 窗户
};

class HouseBuilder {
public:
    virtual ~HouseBuilder() {}

    House* GetResult() {
        return pHouse;
    }

    virtual void BuildFoundation() = 0;  // 构建地基
    virtual void BuildWalls() = 0;       // 构建墙壁
    virtual void BuildRoof() = 0;        // 构建屋顶
    virtual void BuildDoors() = 0;       // 构建门
    virtual void BuildWindows() = 0;     // 构建窗户

protected:
    House* pHouse;
};

class StoneHouseBuilder : public HouseBuilder {
public:
    StoneHouseBuilder() {
        pHouse = new House();
    }

    void BuildFoundation() override {
        pHouse->SetFoundation("石头地基");
    }

    void BuildWalls() override {
        pHouse->SetWalls("石头墙壁");
    }

    void BuildRoof() override {
        pHouse->SetRoof("石头屋顶");
    }

    void BuildDoors() override {
        pHouse->SetDoors("木门");
    }

    void BuildWindows() override {
        pHouse->SetWindows("玻璃窗户");
    }
};


class HouseDirector {
public:
    HouseDirector(HouseBuilder* builder) {
        pHouseBuilder = builder;
    }

    House* Construct() {
        pHouseBuilder->BuildFoundation();  // 构建地基
        pHouseBuilder->BuildWalls();       // 构建墙壁
        pHouseBuilder->BuildRoof();        // 构建屋顶
        pHouseBuilder->BuildDoors();       // 构建门
        pHouseBuilder->BuildWindows();     // 构建窗户

        return pHouseBuilder->GetResult();
    }

private:
    HouseBuilder* pHouseBuilder;
};

int main() {
    HouseBuilder* builder = new StoneHouseBuilder();  // 使用石头房屋构建器
    HouseDirector director(builder);
    House* house = director.Construct();  // 构建房屋
    house->Show();  // 展示房屋部分

    delete house;
    delete builder;
    
    return 0;
}

输出:

房屋部分:
地基:石头地基
墙壁:石头墙壁
屋顶:石头屋顶
门:木门
窗户:玻璃窗户

这时候,假如我们有新需求,需要造一个黄金打造的房子,这时候就很方便了,只需要增加GoldenHouseBuilder 建造器,就可以完成这个扩展,不需要更改以前的代码,满足开放-封闭原则

class GoldenHouseBuilder : public HouseBuilder {
public:
    GoldenHouseBuilder() {
        pHouse = new House();
    }

    void BuildFoundation() override {
        pHouse->SetFoundation("黄金地基");
    }

    void BuildWalls() override {
        pHouse->SetWalls("黄金墙壁");
    }

    void BuildRoof() override {
        pHouse->SetRoof("黄金屋顶");
    }

    void BuildDoors() override {
        pHouse->SetDoors("金门");
    }

    void BuildWindows() override {
        pHouse->SetWindows("钻石窗户");
    }
};

调用过程

    HouseBuilder* goldenBuilder = new GoldenHouseBuilder();  // 使用黄金房屋构建器
    HouseDirector goldenDirector(goldenBuilder);
    House* goldenHouse = goldenDirector.Construct();  // 构建黄金房屋
    goldenHouse->Show();  // 展示黄金房屋部分

    delete goldenHouse;
    delete goldenBuilder;

房屋部分:
地基:黄金地基
墙壁:黄金墙壁
屋顶:黄金屋顶
门:金门
窗户:钻石窗户

四、结构

在这里插入图片描述

五、总结

在软件开发过程中,有时候需要构建具有复杂结构的对象。如果直接在客户端代码中创建和配置这些对象,会导致代码变得复杂且难以维护。此外,如果要构建多个具有不同配置的相似对象,每次都重复编写相似的构建代码也是低效的。为了解决这些问题,可以使用建造者模式。

建造者模式的核心思想是将对象的构建过程从其表示中分离出来。它允许你使用相同的构建过程来创建不同的表示形式。该模式将对象的构建委托给一个单独的建造者对象,该对象负责构建对象的各个部分,并最后返回构建好的对象。

在示例代码中,我们以房屋为例来展示建造者模式的应用。House类代表房屋对象,而HouseBuilder抽象类定义了构建房屋的步骤。StoneHouseBuilderGoldenHouseBuilderHouseBuilder的具体实现,分别用于构建石头房屋和黄金房屋。HouseDirector类负责指导具体建造者对象的构建过程。

通过使用建造者模式,我们可以将房屋对象的构建逻辑与客户端代码分离开来。客户端只需要创建一个合适的具体建造者对象,并将其传递给指导者进行构建。这样可以使客户端代码更简洁、可读性更高,并且在需要构建不同类型的房屋时更加灵活和扩展。

建造者模式适用于构建复杂对象的情况,将构建逻辑与表示分离,使得构建过程更加灵活和可扩展。它提供了一种组织和管理对象构建的方式,避免了繁琐和重复的构建代码。通过委托具体的建造者对象来构建对象,客户端代码可以专注于高级操作,而无需关心对象的内部构建细节。

文章来源:https://blog.csdn.net/weixin_42163707/article/details/134991543
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。