一:概念

Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种。Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象,通过子类继承和重载的方式,动态地创建具有复合属性的对象。
对象的创建:Builder模式是为对象的创建而设计的模式

创建的是一个复合对象:被创建的对象为一个具有复合属性的复合对象

关注对象创建的各部分的创建过程:不同的工厂(这里指builder生成器)对产品属性有不同的创建方法。

二:动机

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

三:代码解析(建造房子)

class House{
//....

House(){ // 错误示例,不能这样写 this->BuildPart1(); // 构造函数中是静态绑定,此时调用纯虚函数会报错,不会去调用子类
for (int i = ; i < ; i++){
this->BuildPart2();
} bool flag = pHouseBuilder->BuildPart3(); if (flag){
this->BuildPart4();
} this->BuildPart5();
} void Init(){ // 流程相对固定 this->BuildPart1(); // 构造第一部分 for (int i = ; i < ; i++){
this->BuildPart2();
} bool flag = pHouseBuilder->BuildPart3(); if (flag){
this->BuildPart4();
} this->BuildPart5();
}
virtual ~HouseBuilder(){}
protected:
virtual void BuildPart1() = ;
virtual void BuildPart2() = ;
virtual void BuildPart3() = ;
virtual void BuildPart4() = ;
virtual void BuildPart5() = ;
};
C++构造函数中,是不会去调用子类的虚函数。
子类构造函数会先去调用父类构造函数,如果子类调用父类构造,父类构造中去寻找子类虚函数,会报错,因为子类构造函数还没有完成,子类虚函数先被调用,这违背对象的构造原理
class StoneHouse: public House{  //各种房子

protected:

    virtual void BuildPart1(){
//pHouse->Part1 = ...;
}
virtual void BuildPart2(){ }
virtual void BuildPart3(){ }
virtual void BuildPart4(){ }
virtual void BuildPart5(){ }
};

四:模式定义

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

                                              --《设计模式》Gof   
Init就是同一个构建过程,而每一个对象我们只需要实现其构建步骤就可以创建不同的表示
int main()
{
House* pHouse = new StoneHouse();
pHouse->Init();
}

五:进一步优化(对象过于复杂,除了上面步骤还有其他方法和属性)

class House{ // 表示  抽象基类
//.... house 与 HouseBuilder 相分离
}; 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{ }; 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* pHouseBuilder; HouseDirector(HouseBuilder* pHouseBuilder){
this->pHouseBuilder=
pHouseBuilder;
}
House* Construct(){ pHouseBuilder->BuildPart1(); for (int i = ; i < ; i++){
pHouseBuilder->BuildPart2();
} bool flag=pHouseBuilder->BuildPart3(); if(flag){
pHouseBuilder->BuildPart4();
} pHouseBuilder->BuildPart5(); return pHouseBuilder->GetResult();
}
};
HouseBuilder管构建,House将其分离出去,而创建步骤又是稳定的,我们再一步进行拆分为HouseDiretor,避免类的肥大

六:类图(结构)

类复杂就拆分,类简单就合并

七:要点总结

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

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

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

八:构建器和工厂模式区别

(一)Factory模式中:

.有一个抽象的工厂。
.实现一个具体的工厂---汽车工厂。
.工厂生产汽车A,得到汽车产品A。
.工厂生产汽车B,得到汽车产品B。
这样做,实现了购买者和生产线的隔离。

(二)Builder模式:

.离合器工厂生产离合器产品,得到汽车部件A。
.轮胎工厂生产轮子产品,得到汽车部件B。
.车身工厂生产车身产品,得到汽车部件C。
.将这些部件放到一起,形成刚好能够组装成一辆汽车的整体。
.将这个整体送到汽车组装工厂,得到一个汽车产品。
或者更抽象一点理解:
.将汽车的每一个零件都送到汽车组装工厂。
.在工厂里,组装离合器,得到汽车部件A。
.在工厂里,组装轮胎,得到汽车部件B。
.在工厂里,组装车身,得到汽车部件C。
.在工厂里,组装每个部件,得到一个汽车产品。
这样做,目的是为了实现复杂对象生产线和其部件的解耦。

(三)二者不同在于:

Factory模式不考虑对象的组装过程,而直接生成一个我想要的对象。
Builder模式先一个个的创建对象的每一个部件,再统一组装成一个对象。
Factory模式所解决的问题是,工厂生产产品。而Builder模式所解决的问题是工厂控制产品生成器组装各个部件的过程,然后从产品生成器中得到产品。

九:案例实现(建房子)

(一)实现抽象类Director(工程师),House(房子),HouseBuilder(工程队)

class House
{
private:
string m_floor;
string m_wall;
string m_door;
public:
void setFloor(string floor)
{
this->m_floor = floor;
} void setWall(string wall)
{
this->m_wall = wall;
} void setDoor(string door)
{
this->m_door = door;
} void getFloor()
{
cout << "install " << this->m_floor << endl;
} void getWall()
{
cout << "install " << this->m_wall << endl;
} void getDoor()
{
cout << "install " << this->m_door << endl;
}
}; class HouseBuilder
{
protected:
House* pHouse; public:
virtual void BuildFloor() = ;
virtual void BuildWall() = ;
virtual void BuildDoor() = ; House* GetResult()
{
return pHouse;
}
}; class HouseDirector
{
public:
HouseBuilder* pHouseBuilder; HouseDirector(HouseBuilder* pHouseBuilder)
{
this->pHouseBuilder = pHouseBuilder;
} House* Construct()
{
pHouseBuilder->BuildWall();
pHouseBuilder->BuildFloor();
pHouseBuilder->BuildDoor();
return pHouseBuilder->GetResult();
}
};

(二)实现具体房子类和建造类

class StoneHouseBuilder :public HouseBuilder
{
public:
StoneHouseBuilder()
{
pHouse = new House();
} virtual void BuildFloor()
{
pHouse->setFloor("stone floor");
} virtual void BuildWall()
{
pHouse->setWall("stone wall");
} virtual void BuildDoor()
{
pHouse->setDoor("stone door");
}
}; class FlatHouseBuilder :public HouseBuilder
{
public:
FlatHouseBuilder()
{
pHouse = new House();
} virtual void BuildFloor()
{
pHouse->setFloor("flat floor");
} virtual void BuildWall()
{
pHouse->setFloor("flat wall");
} virtual void BuildDoor()
{
pHouse->setFloor("flat door");
}
};

(三)工程师步骤指挥,按步骤创建房屋

void main()
{
HouseBuilder* HB = new StoneHouseBuilder();
HouseDirector* HD = new HouseDirector(HB);
House* H = HD->Construct(); H->getWall();
H->getFloor();
H->getDoor(); delete H;
delete HB;
delete HD; system("pause");
return;
}

设计模式---对象创建模式之构建器模式(Builder)的更多相关文章

  1. 深入探索Java设计模式(三)之装饰器模式

    装饰器模式使你可以在运行时使用类似于对象组成的技术来装饰类.这在我们希望实例化具有新职责的对象而无需对基础类进行任何代码更改的情况下尤其有用.本文是在学习完优锐课JAVA架构VIP课程—[框架源码专题 ...

  2. 深入探索Java设计模式之构建器模式(五)

    抽丝剥茧 细说架构那些事——[优锐课] 简单的程序不需要大量的设计过程,因为它们只关注有限的解决方案,仅使用几个类.大型程序专注于广泛的设计,该设计比好的设计范例的任何其他属性都更能利用可重用性.宏伟 ...

  3. Java设计模式:Builder(构建器)模式

    概念定义 Builder模式是一步一步创建一个复杂对象的创建型模式.该模式将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的表示隔离开来. 应用场景 对象创建过程比较复杂,或对创建顺序或组合有依 ...

  4. Java进阶篇设计模式之五-----外观模式和装饰器模式

    前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...

  5. Java设计模式之五 ----- 外观模式和装饰器模式

    前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...

  6. 23种设计模式 - 对象创建(FactoryMethod - AbstractFactory - Prototype - Builder)

    其他设计模式 23种设计模式(C++) 每一种都有对应理解的相关代码示例 → Git原码 ⌨ 对象创建 通过"对象创建" 模式绕开new,来避免对象创建(new)过程中所导致的紧耦 ...

  7. 设计模式---对象创建模式之抽象工厂模式(Abstract Factory)

    一:概念 抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的.抽象工厂模式可以向客户端提供一个接口,使得客户端在不必指定产品的具体类型的情况下,能够创建多个产品族的产品对象 二:动机 在软件系统 ...

  8. 设计模式---对象创建模式之工厂方法模式(Factory Method)

    前提:“对象创建”模式 通过“对象创建”模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定.它是接口抽象之后的第一步工作. 典型模式(表现最为突出) 工 ...

  9. 设计模式---对象创建模式之原型模式(prototype)

    一:概念 原型模式(Prototype Pattern) 实际上就是动态抽取当前对象运行时的状态 Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例.使用Protot ...

随机推荐

  1. Practice3 阅读《构建之法》1-5章

    第一章:概论 本章主要是讲了软件工程的基本概念,软件工程的最终目标是创造“足够好”的软件. 提出问题:什么是BUG?(出自1.2.5节) 答:就我个人而言,在许多游戏中也有许多的BUG,BUG这一词在 ...

  2. Android 學習之旅!(1)

    就這樣就過去了一年加一個學期,現在是大二第二個學期而且是下半學期了,以前都是無所事事,沒事睡睡覺,打打遊戲就過去了,但是想到家境和以後的路,我還是決心自己找點東西學習下,以後出去還能有一技之長(雖然可 ...

  3. weex 开发踩坑日记--环境配置、安卓运行、adb、开发

    环境配置方面 1.需要安装java和android环境,java的话一定要下载jdk而不是jre. 在"系统变量"新建一个变量名为JAVA_HOME的变量,变量值为你本地java的 ...

  4. PAT 1002 写出这个数

    https://pintia.cn/problem-sets/994805260223102976/problems/994805324509200384 读入一个自然数n,计算其各位数字之和,用汉语 ...

  5. CentOS(6.8)7 安装 Mysql 5.7

    https://blog.csdn.net/zyw_java/article/details/70949596 https://blog.csdn.net/yzl11/article/details/ ...

  6. An internal error has occurred. Java heap space

    http://stackoverflow.com/questions/11001252/running-out-of-heap-space issue: I am having a heap spac ...

  7. Activiti流程编辑器针对自定义用户角色表优化改造

    本文目的: 针对自定义的用户.角色表,对Activiti的在线流程设计器进行优化改造,使之能直接在图形界面上完成对节点办理人.候选人.候选组的配置,不需要先去查数据库中的用户ID.角色ID等信息再填入 ...

  8. [转帖]ARM 相关内容

    ARM内核全解析,从ARM7,ARM9到Cortex-A7,A8,A9,A12,A15到Cortex-A53,A57 http://www.myir-tech.com/resource/448.asp ...

  9. matplotlib绘图

    fig = plt.figure() ax=plt.gca() timeList = np.array(timeList) timeList=timeList*100 timeList1 = np.a ...

  10. Idea for Mac 过期 IntelliJ IDEA 2017 完美注册方法(附idea for Mac破解方法)

    Idea 不能使用了: 开始破解: (1)首先下载 jar包: https://download.csdn.net/download/engerla/10573069 放到位置: /Applicati ...