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

Posted 老樊Lu码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++Builder建造者模式详解--设计模式相关的知识,希望对你有一定的参考价值。

Builder模式来源:         

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

Builder模式作用:

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

Builder模式的UML结构图如图1所示:

                          

         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 <string>
#include <vector>

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 <iostream>
#include <vector>

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!"<<endl;
}

void ConcreteBuilder1::BuildPartA()
{
    this->m_pProduct->setPartA("A");
    cout<<"BuildPartA"<<endl;
}

void ConcreteBuilder1::BuildPartB()
{
    this->m_pProduct->setPartB("B");
    cout<<"BuildPartB"<<endl;
}

void ConcreteBuilder1::BuildPartC()
{
    this->m_pProduct->setPartC("C");
    cout<<"BuildPartC"<<endl;
}

Product* ConcreteBuilder1::GetProduct()
{
    return this->m_pProduct;
}

ConcreteBuilder1::~ConcreteBuilder1()
{
    delete this->m_pProduct;
    this->m_pProduct = NULL;
}

ConcreteBuilder2::ConcreteBuilder2()
{
    this->m_pProduct = new Product();
    cout<<"Create empty product!"<<endl;
}

void ConcreteBuilder2::BuildPartA()
{
    this->m_pProduct->setPartA("A");
    cout<<"BuildPartA"<<endl;
}

void ConcreteBuilder2::BuildPartB()
{
    this->m_pProduct->setPartB("B");
    cout<<"BuildPartB"<<endl;
}

void ConcreteBuilder2::BuildPartC()
{
    this->m_pProduct->setPartC("C");
    cout<<"BuildPartC"<<endl;
}

Product* ConcreteBuilder2::GetProduct()
{
    return this->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 <iostream>

using namespace std;

int main()
{
    Director* pDirector = new Director(new ConcreteBuilder1());
    pDirector->Construct();

    Director* pDirector1 = new Director(new ConcreteBuilder2());
    pDirector1->Construct();

    return 0;
}

Builder模式的使用总结:

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

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




以上是关于C++Builder建造者模式详解--设计模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式-- 建造者模式详解

建造者模式(Builder)

《设计模式》之建造者模式(Builder)

[05]Go设计模式:建造者模式(Builder Pattern)

什么是建造者模式

设计模式-建造者模式(Builder)