定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
 
结构
 
理解
1.       生成器(Builder)模式是一步步构建一个复杂的产品,它允许用户可以只通过指定复杂对象的类型和内容就可以构建它们,用户不知道内部的具体构建细节。
2.       Builder基类创建复杂产品(Product)全过程的抽象基类。Builder基类提供若干个构造部件(BuildPart)的方法(基类提供缺省实现)。具体构建产品的过程由ConcreteBuilder实现,GetResult()是获取构造完成后的对象(该方法并不在基类中!因为产品Product一般没有抽象基类。如果产品有抽象基类,GetResult就可以放在基类里)。
3.       Director在构造函数中调用Builder的构造部件方法,当最后一个部件方法调用完成后,就产生了一个复杂的产品Director的作用是封装一个产品的各个部件装配过程。
4.       Builder基类将公共的部分提取出来,各个部件方法(BuildPart)由子类扩展实现。
5.       Director中聚合了Builder基类指针,这样可以适应不同的具体构建者。
 
要点
1.       生成器模式将构建复杂对象的部件和构建过程(算法)解耦。生产一辆汽车的部件有车轮、发动机等等,装配一辆汽车的过程是很复杂的。应用Builder模式,生产部件(Builder.BuilderPart方法)和汽车装配过程(Director角色)是可以分开的。
2.       生成器模式构建的对象,部件可以不同,但构建过程是一样的。不同品牌的汽车生产流程相同,但由于部件的差别导致品牌地位差异。
3.       生成器模式与抽象工厂模式都是创建复杂对象,他们之间的差别比较:
Builder模式强调的是一步步构建一个复杂的对象。Abstract Factory强调多个系列的产品对象,并不关注复杂性。
Builder是生成若干个组件后,最后一步返回对象。Abstract Factory是立即返回对象的。
 
应用
网络协议解析器的场景。譬如要对某种协议数据进行解析,数据解析过程包括获取协议类型、解密、解析包头、解析包体。不管协议类型如何变化,解析的过程是不会变化的。解析这些数据的类就是生成器(Builder),包括解析包头等等方法。
源码中通过简单的汽车生产例子来说明生成器模式。
 
源码
#include <iostream>
#include <string>
using namespace std;
 
//product
class CBMW
{
public:
    //飚车
    void Race()
    {
        cout << "race with BMW!" << endl;
    }
};
 
class CBYD
{
public:
    //用来出租了
    void Taxi()
    {
        cout << "taxi with BYD!" << endl;
   }
};
 
//Builder
class CAutoBuilder
{
public:
    virtual ~CAutoBuilder(){};
 
    //发动机
    virtual void BuildEngine(){};
    //车轮
    virtual void BuildWheel(){};
    //车载导航. 低档车是没有的, 就不实现该方法
    virtual void BuildNavigation(){};
};
 
class CBMWBuilder : public CAutoBuilder
{
public:
    CBMWBuilder() : m_pCar(new CBMW){};
    ~CBMWBuilder()
    {
        delete m_pCar;
    };
 
    virtual void BuildEngine()
    {
        cout << "BMW build engine" << endl;
    };
 
    virtual void BuildWheel()
    {
        cout << "BMW build wheels" << endl;
    };
 
    virtual void BuildNavigation()
    {
        cout << "BMW build navigation" << endl;
    };
 
    CBMW* GetBMW()
    {
        return m_pCar;
    }
protected:
    CBMW* m_pCar;
};
 
//byd没有导航,就实现部件方法了
class CBYDBuilder : public CAutoBuilder
{
public:
    CBYDBuilder() : m_pCar(new CBYD){};
    ~CBYDBuilder()
    {
        delete m_pCar;
    };
 
    virtual void BuildEngine()
    {
        cout << "BYD build engine" << endl;
    };
 
    virtual void BuildWheel()
    {
        cout << "BYD build wheels" << endl;
    };
 
    CBYD* GetBYD()
    {
        return m_pCar;
    }
 
protected:
    CBYD* m_pCar;
};
 
//指导者
class CDirector
{
public:
    //组装过程。不管什么车都组装过程一样
    CDirector(CAutoBuilder* pAutoBuilder)
    {
        pAutoBuilder->BuildEngine();
        pAutoBuilder->BuildWheel();
        pAutoBuilder->BuildNavigation();
    }
};
 
 
int main()
{
    CBYDBuilder bydBuilder;
    CDirector d1(&bydBuilder); //我们不关心是如何组装的
    CBYD* pByd = bydBuilder.GetBYD();
    pByd->Taxi();
 
    CBMWBuilder bmwBuilder;
    CDirector d2(&bmwBuilder);
    CBMW* pBmw = bmwBuilder.GetBMW();
    pBmw->Race();
 
    system("pause");
    return 0;
}
 
输出:
BYD build engine
BYD build wheels
taxi with BYD!
BMW build engine
BMW build wheels
BMW build navigation
race with BMW!

转载本站文章请注明,转载自:神秘果

本文链接: http://www.shenmiguo.com/archives/2009/292_design-patterns-builder.html

Leave a Reply

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <font color="" face="" size=""> <span style="">