C++设计模式之构造器

动机

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

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

代码示例:建立各种房子,比如砖瓦房,高楼,别墅等房子

cpp 复制代码
class House{
    //....
};

class HouseBuilder {
public:
    House* GetResult(){
        return pHouse;
    }
    virtual ~HouseBuilder(){}
protected:
    
    House* pHouse;
	virtual void BuildPart1()=0;
    virtual void BuildPart2()=0;
    virtual void BuildPart3()=0;
    virtual void BuildPart4()=0;
    virtual void BuildPart5()=0;
	
};

class StoneHouse: public House{
    
};

// 石头房子的创建,override HouseBuilder里面的流程
class StoneHouseBuilder: public HouseBuilder{
protected:
    
    virtual void BuildPart1(){
        //pHouse->Part1 = ...;
    }
    virtual void BuildPart2(){
        
    }
    virtual void BuildPart3(){
        
    }
    virtual void BuildPart4(){
        
    }
    virtual void BuildPart5(){
        
    }
    
};

// 房子具体构建过程
class HouseDirector{
    
public:
    // 有一个HouseBuilder的指针
    HouseBuilder* pHouseBuilder;
    
    HouseDirector(HouseBuilder* pHouseBuilder){
        this->pHouseBuilder=pHouseBuilder;
    }
    
    House* Construct(){ // 整个构建流程是稳定的
        
        pHouseBuilder->BuildPart1();
        
        for (int i = 0; i < 4; i++){
            pHouseBuilder->BuildPart2();
        }
        
        bool flag=pHouseBuilder->BuildPart3();
        
        if(flag){
            pHouseBuilder->BuildPart4();
        }
        
        pHouseBuilder->BuildPart5();
        
        return pHouseBuilder->GetResult();
    }
};

int main() {
    // 创建石头房子的建造者
    StoneHouseBuilder stoneHouseBuilder;

    // 创建房子Director,并指定建造者
    HouseDirector houseDirector(&stoneHouseBuilder);

    // 构建房子
    House* stoneHouse = houseDirector.Construct();

    // 输出结果
    if (stoneHouse != nullptr) {
        // 假设 House 类有适当的输出方法
        // 这里只是简单示例,实际使用时需要根据具体类的实现调用相应的方法
        std::cout << "Stone House constructed." << std::endl;
    } else {
        std::cout << "Failed to construct Stone House." << std::endl;
    }

    // 释放资源
    delete stoneHouse;

    return 0;
}

上述代码涉及了Builder设计模式,包括以下几个类:

House 类:

表示待构建的产品,即房子。在示例中,StoneHouse 类是 House 的具体实现。

HouseBuilder 抽象类:

定义了构建产品(房子)的抽象接口。具体的建造者(例如 StoneHouseBuilder)需要继承这个抽象类并实现接口中的方法,以完成具体产品的构建。

StoneHouseBuilder 类:

HouseBuilder的具体实现,负责构建石头房子。它通过实现抽象接口中的方法来完成具体的建造流程。

HouseDirector 类:

起到指导建造的作用,通过构造函数接收一个具体的建造者对象。通过调用建造者的方法,按照一定的构建流程组织建造者完成产品的构建。
main 函数:

main 函数中,创建了 StoneHouseBuilder 的实例,然后创建了一个HouseDirector的实例,并将建造者传递给导演。通过导演的 Construct 方法,按照一定的构建流程构建了石头房子,并输出结果。

总体而言,Builder设计模式的目的是将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。在这个示例中,HouseBuilder 抽象类定义了构建房子的接口,StoneHouseBuilder 实现了具体的石头房子构建流程,而 HouseDirector 则负责协调建造者完成整个构建流程。

Builder要点总结

Builder 模式主要用于"分步骤构建一个复杂的对象"。在这其中"分步骤"是一个稳定的算法,而复杂对象的各个部分则经常变化。

变化点在哪里,封装哪里------ Builder模式主要在于应对"复杂对象各个部分"的频繁需求变动。其缺点在于难以应对"分步骤构建算法"的需求变动。

在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs. C#) 。

chatGPT给出的builder的例子

以下是一个简单的C++示例代码,演示Builder设计模式:

cpp 复制代码
#include <iostream>
#include <string>

// 产品类
class Product {
public:
    void AddPart(const std::string& part) {
        parts += part + " ";
    }

    void Show() const {
        std::cout << "Product Parts: " << parts << std::endl;
    }

private:
    std::string parts;
};

// 抽象建造者类
class Builder {
public:
    virtual void BuildPart1() = 0;
    virtual void BuildPart2() = 0;
    virtual Product* GetResult() = 0;
};

// 具体建造者类
class ConcreteBuilder : public Builder {
public:
    ConcreteBuilder() {
        product = new Product();
    }

    void BuildPart1() override {
        product->AddPart("Part1");
    }

    void BuildPart2() override {
        product->AddPart("Part2");
    }

    Product* GetResult() override {
        return product;
    }

private:
    Product* product;
};

// 指导者类
class Director {
public:
    Director(Builder* builder) : builder(builder) {}

    void Construct() {
        builder->BuildPart1();
        builder->BuildPart2();
    }

private:
    Builder* builder;
};

int main() {
    // 创建具体建造者
    ConcreteBuilder concreteBuilder;

    // 创建指导者,并传入具体建造者
    Director director(&concreteBuilder);

    // 指导者构建产品
    director.Construct();

    // 获取最终产品
    Product* product = concreteBuilder.GetResult();

    // 展示产品
    if (product != nullptr) {
        product->Show();
        delete product;
    }

    return 0;
}

在这个示例中,Product 表示最终构建的复杂对象,Builder 是抽象建造者类,ConcreteBuilder 是具体建造者类,Director 是指导者类。通过指导者调用具体建造者的方法,最终得到构建完成的产品。这个例子中的产品是简单的包含两个部分的字符串,实际应用中可以根据需求定义更复杂的产品结构。

相关推荐
羊小猪~~6 分钟前
C/C++语言基础--C++STL库算法记录(质变算法、非质变算法、查找、排序、排列组合、关系算法、集合算法、堆算法等)
c语言·开发语言·数据结构·c++·算法·stl
程序员老冯头12 分钟前
第三十六章 C++ 多线程
java·c++·信号处理
weixin_749949901 小时前
双向列表的实现(C++)
开发语言·c++·链表
xianwu5432 小时前
反向代理模块开发,
linux·开发语言·网络·c++·git
silver6872 小时前
状态模式详解
设计模式
JINGWHALE12 小时前
设计模式 行为型 状态模式(State Pattern)与 常见技术框架应用 解析
前端·人工智能·后端·设计模式·性能优化·系统架构·状态模式
lzb_kkk2 小时前
【C++】JsonCpp库
开发语言·c++·json·1024程序员节
智驾2 小时前
SOLID原则学习,开闭原则
c++·开闭原则·solid
至暗时刻darkest3 小时前
STM32 单片机 练习项目 LED灯闪烁&LED流水灯&蜂鸣器 未完待续
c++·单片机
飞飞是甜咖啡3 小时前
【Orca】Orca - Graphlet 和 Orbit 计数算法
c语言·c++·人工智能·python