首页 > 其他分享 >构建器模式 Builder

构建器模式 Builder

时间:2022-09-27 20:00:20浏览次数:52  
标签:StoneHouse House void pHouseBuilder virtual 构建 模式 Builder

“对象创建”模式

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

这个模式用的比较少。比较像模板方法模式。

动机(Motivation)

  • 在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
  • 如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?

C++ 中构造函数你调用虚函数是静态绑定。因为派生类的构造函数先调用基类的构造函数。

模式定义

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

代码示例

#include <iostream>
using namespace std;

class House
{
public:
    void Init()
    {
        BuildPart1();
        // 建四个窗
        for (int i = 0; i < 4; i++) {
            BuildPart2();
        }
        bool flag = BuildPart3();
        if (flag) {
            BuildPart4();
        }
        BuildPart5();
    }
    virtual ~House(){}

protected:
    virtual void BuildPart1() = 0;
    virtual void BuildPart2() = 0;
    virtual bool BuildPart3() = 0;
    virtual void BuildPart4() = 0;
    virtual void BuildPart5() = 0;
};

class StoneHouse: public House
{
protected:
    virtual void BuildPart1()
    {
        cout << "part" << 1 << endl;
    }
    virtual void BuildPart2()
    {
        cout << "part" << 2 << endl;
    }
    virtual bool BuildPart3()
    {
        cout << "part" << 3 << endl;
        return true;
    }
    virtual void BuildPart4()
    {
        cout << "part" << 4 << endl;
    }
    virtual void BuildPart5()
    {
        cout << "part" << 5 << endl;
    }
};

int main()
{
    House *pHouse = new StoneHouse;
    pHouse->Init(); // 完成构建。  C++ 中构造函数里面的虚函数调用是静态绑定的,所以这里用 Init 函数。

    getchar();
    return 0;
}

输出:

part1
part2
part2
part2
part2
part3
part4
part5

修改版,根据自己理解写的,不太确定是不是这个意思:

#include <iostream>
#include <string>
using namespace std;

// 抽象基类
class House {
public:
    void showInfo()
    {
        cout << one << two << three << four << five << endl;
    }
    virtual void Do() = 0;
protected:
    string one;
    string two;
    string three;
    string four;
    string five;
};

// 抽象基类
class HouseBuilder {
public:
    House* GetResult() {
        return pHouse;
    }
    virtual ~HouseBuilder() {}
    HouseBuilder(House *house) :pHouse(house)
    {
    }
protected:
    House* pHouse;
public:
    virtual void BuildPart1() = 0;
    virtual void BuildPart2() = 0;
    virtual bool BuildPart3() = 0;
    virtual void BuildPart4() = 0;
    virtual void BuildPart5() = 0;
};

class StoneHouse : public House {
public:
    virtual void Do()
    {
        cout << "石头房:";
        showInfo();
    }
    friend class StoneHouseBuilder;
};

class StoneHouseBuilder : public HouseBuilder {
public:
    StoneHouseBuilder(House *house) :HouseBuilder(house) {}
protected:
    virtual void BuildPart1() {
        StoneHouse* p = static_cast<StoneHouse*>(pHouse); // 友元不能继承?
        p->one = "一座屋,";
    }
    virtual void BuildPart2() {
        StoneHouse* p = static_cast<StoneHouse*>(pHouse);
        p->two += "两间房,";
    }
    virtual bool BuildPart3() {
        StoneHouse* p = static_cast<StoneHouse*>(pHouse);
        p->three = "三扇门,";
        return true;
    }
    virtual void BuildPart4() {
        StoneHouse* p = static_cast<StoneHouse*>(pHouse);
        p->four = "四个窗,";
    }
    virtual void BuildPart5() {
        StoneHouse* p = static_cast<StoneHouse*>(pHouse);
        p->five = "五张桌。";
    }
};

class HouseDirector {
    HouseBuilder* pHouseBuilder;
public:
    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()
{
    StoneHouse stoneHouse;
    StoneHouseBuilder stoneHouseBuilder(&stoneHouse);
    HouseDirector houseDirector(&stoneHouseBuilder);

    House* myHouse = houseDirector.Construct();
    myHouse->Do();

    getchar();
    return 0;
}

输出:

石头房:一座屋,两间房,两间房,两间房,两间房,三扇门,四个窗,五张桌。

类图

要点总结

  • Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。
  • 变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。
  • 在Builder模式中,要注意不同语言中构造器内调用虚函数的差别(C++ vs. C#) 。




参考:GeekBand

标签:StoneHouse,House,void,pHouseBuilder,virtual,构建,模式,Builder
From: https://www.cnblogs.com/huvjie/p/16734667.html

相关文章

  • 03-Go设计模式-工厂方法模式
    工厂模式方法模式示例代码/*工厂方法模式抽象工厂(AbstractFactory)角色:工厂方法模式的核心,任何工厂类都必须实现这个接口工厂(ConcreteFactory)角色:具体工厂类是抽象工......
  • 02-Go设计模式-简单工厂
    简单工厂模式示例代码/*简单工厂模式角色和职责工厂(Factory)角色:简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象......
  • 组合模式
    组合模式职务接口packagecompositetypejobberinterface{ setJob(string) setManager(jobber) addSubordinate(jobber) print(string)}职务节点packagecom......
  • 设计模式 -- Prototype(原型模式)
    原型模式(Prototype)使用原型实例指定创建对象的种类,然后通过拷贝这些原型来创建新的对象。在软件系统中,经常面临着“某些结构复杂的对象”的创建工作;由于需求的变化,这些......
  • Hiwin直线电机C#MPI控制程序<通讯设置、回原点设置、点动模式、点对点运动、依托Timer
    一、通讯设定与连接√说明与总结:布尔量Connect为驱动器连接与否的标识符,启动时默认为false,即未连接状态; /*-----------------------------------------------*/......
  • Hbuilderx中mac链接android模拟器
    1、打开了mumu模拟器。2、hBuilderX=>运行=>abd路径设置=>只需要填写android模拟器端口7555(网易mumu模拟器对应的,每个模拟器有自己的,具体查看文档)3、./adbki......
  • StringBuilder的用法
    当我们要对字符串做多次变化时,我们可以考虑用StringBuilderStringBuildersb=newStringBuilder();sb.Append("111");//追加字符串sb.AppendLine("222");//追加一行字......
  • 线程优雅停止-两阶段终止模式
    所谓优雅停止,即即将在停止的线程足够的时间完成善后工作,而不是直接杀死线程。假设此时某线程正在独占资源(占有锁),突然对线程的终止,会导致其占有的资源无法得到释放,其他线程......
  • hbuilderx 编译报错cannot find module ‘yallist’
    更新后的Hbuilder X报错error:cannotfindmodule‘yallist’解决方案打开huilberx-工具-插件安装  卸载重装,重启hbuilderx。重新编译即可......
  • 在MVVM模式下使用命令传多个参数的问题
    最近碰到一个问题,在MVVM模式下进行命令传参时需要传递两个参数:例如类型和ID 解决方法如下<i:Interaction.Triggers><i:EventTriggerEventName=......