欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++Builder建造者模式详解--设计模式(4)

程序员文章站 2022-05-25 17:07:44
生活中有着很多的builder的例子,个人觉得大学生活就是一个builder模式的最好体验:要完成大学教育,一般将大学教育过程分成4个学期进行,因此没有学习可以看作是构建完整大学教育的一个部分构建过...

生活中有着很多的builder的例子,个人觉得大学生活就是一个builder模式的最好体验:要完成大学教育,一般将大学教育过程分成4个学期进行,因此没有学习可以看作是构建完整大学教育的一个部分构建过程,每个人经过这4年的(4个阶段)构建过程得到的最后的结果不一样,因为可能在四个阶段的构建中引入了很多的参数(每个人的机会和际遇不完全相同)。

builder模式要解决的也正是这样的问题:当我们要创建的对象很复杂的时候(通常是由很多其他的对象组合而成),我们要要复杂对象的创建过程和这个对象的表示(展示)分离开来,这样做的好处就是通过一步步的进行复杂对象的构建,由于在每一步的构造过程中可以引入参数,使得经过相同的步骤创建最后得到的对象的展示不一样。

builder模式的uml结构图如图1所示:

C++Builder建造者模式详解--设计模式(4)

  builder模式的关键是其中的director对象并不直接返回对象,而是通过一步步(buildparta,buildpartb,buildpartc)来一步步进行对象的创建。当然这里director可以提供一个默认的返回对象的接口(即返回通用的复杂对象的创建,即不指定或者特定唯一指定buildpart中的参数)。

  builder模式的实现基于以下几个面向对象的设计原则:

  1)把变化的部分提取出来形成一个基类和对应的接口函数,在这里不会变化的是都会创建parta和partb,变化的则是不同的创建方法,于是就抽取出这里的builder基类和buildparta,buildpartb接口函数

  2)采用聚合的方式聚合了会发生变化的基类,就是这里director聚合了builder类的指针.

  以上,通过两个派生类concretebuilder1、concretebuilder2定义了两种不同的建造细节(建造步骤是一样的,由construct函数确定),通过两个派生类所建造出来的对象,对外部所展现出来的属性或者功能是不一样的,由各自builder派生类中的建造方法(buildparta、buildpartb、buildpartc)决定。

builder.h

 

#ifndef _builder_h_
#define _builder_h_

#include 
#include 

using namespace std;

//产品类
class product
{
private:
    string m_parta;
    string m_partb;
    string m_partc;
public:
    void setparta(const string& s);
    void setpartb(const string& s);
    void setpartc(const string& s);
    product();
    ~product();
};

//抽象builder基类,定义不同部分的创建接口
class builder
{
public:
    virtual void buildparta()=0;
    virtual void buildpartb()=0;
    virtual void buildpartc()=0;
    virtual product* getproduct()=0;
    builder();
    virtual ~builder();
};

//  builder的派生类,实现builderparta和builderpartb和buildpartc接口函数 
class concretebuilder1:public builder
{
public:
    concretebuilder1();
    ~concretebuilder1();
    virtual void buildparta();
    virtual void buildpartb();
    virtual void buildpartc();
    virtual product* getproduct();
private:
    product* m_pproduct;
};

//  builder的派生类,实现builderparta和builderpartb和buildpartc接口函数 
class concretebuilder2:public builder
{
public:
    concretebuilder2();
    ~concretebuilder2();
    virtual void buildparta();
    virtual void buildpartb();
    virtual void buildpartc();
    virtual product* getproduct();
private:
    product* m_pproduct;
};

//concretebuilder1与concretebuilder2是builder的两个派生类,用于实现两种不同的建造细节

 // 使用builder构建产品,构建产品的过程都一致,但是不同的builder有不同的实现
 // 这个不同的实现通过不同的builder派生类来实现,存有一个builder的指针,通过这个来实现多态调用 
class director
{
public:
    director(builder* pbuilder);
    ~director();

    //construct函数定义一个对象的整个构建过程,不同的部分之间的装配方式都是一致的,
    //首先构建parta其次是partb,只是根据不同的构建者会有不同的表示 
    void construct();
    //void construct(const string& buildpara);
private:
    builder* m_pbuilder;
};

#endif

 

director.cpp

 

#include "builder.h"
#include 
#include 

using namespace std;

product::~product()
{
}

product::product()
{}

void product::setparta(const string& s)
{
    this->m_parta = s;
}

void product::setpartb(const string& s)
{
    this->m_partb = s;
}

void product::setpartc(const string& s)
{
    this->m_partc = s;
}

builder::builder()
{}

builder::~builder()
{}

concretebuilder1::concretebuilder1()
{
    this->m_pproduct = new product();
    cout<<"create empty product!"<m_pproduct->setparta("a");
    cout<<"buildparta"<m_pproduct->setpartb("b");
    cout<<"buildpartb"<m_pproduct->setpartc("c");
    cout<<"buildpartc"<m_pproduct;
}

concretebuilder1::~concretebuilder1()
{
    delete this->m_pproduct;
    this->m_pproduct = null;
}

concretebuilder2::concretebuilder2()
{
    this->m_pproduct = new product();
    cout<<"create empty product!"<m_pproduct->setparta("a");
    cout<<"buildparta"<m_pproduct->setpartb("b");
    cout<<"buildpartb"<m_pproduct->setpartc("c");
    cout<<"buildpartc"<m_pproduct;
}

concretebuilder2::~concretebuilder2()
{
    delete this->m_pproduct;
    this->m_pproduct = null;
}

director::director(builder* pbuilder)
{
    this->m_pbuilder = pbuilder;
}

void director::construct()
{
    this->m_pbuilder->buildparta();
    this->m_pbuilder->buildpartb();
    this->m_pbuilder->buildpartc();
}

director::~director()
{
    delete this->m_pbuilder;
    this->m_pbuilder = null;
}
main.cpp

 

 

#include "builder.h"
#include 

using namespace std;

int main()
{
    director* pdirector = new director(new concretebuilder1());
    pdirector->construct();

    director* pdirector1 = new director(new concretebuilder2());
    pdirector1->construct();

    return 0;
}

建造者模式和工厂模式使用很相似,但也有区别:

 

 

建造者模式最主要功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了;而工厂方法则重点是创建,你要什么对象我创造一个对象出来,组装顺序则不是他关心的。

建造者模式使用的场景,一是产品类非常的复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式是非常合适。




 

;>
;>
;>
;>
;>
;>
;>
;>