[原创][创建型模式] 建造者模式的理解

我的理解
    在实际的项目中,很多时候我们和一些设备的沟通都是通过数据流来完成的。用户和设备通过固定格式的包进行处理。实际项目
中使用的一个实例如下:Application Package Format:{CmdCode}{Type}{P1}{P2}{Len}{Data}
    这样的一个包具有严格的格式,同时不同参数具有不同的意义,这样一来,就可以理解为一个典型的Builder Pattern。

流程:
    用户代表了客户端的行为,所以逻辑如下:
    (1)用户连接设备,按照协议,确定数据包的组成,一个完整的数据包其实本质就一个Product;
    (2)确定数据包的组成部分之后,我们需要确定各个数据组成的先后顺序(Director);实例中,数据包的顺序是1、2、3、4、5;
但是根据不同的情况,修改成4、1、2、3、5,也是很有可能的;
    (3)利用原始的组成数据按照一定顺序组成一个完整的数据包;




头文件
//BuilderPattern.h

#ifndef BUILDER_PATTERN_H
#define BUILDER_PATTERN_H

#include <Windows.h>
#include <string>
using namespace std;

namespace BuilderPattern
{
    class Product
    {
    public:
        Product();
        ~Product();

        void AddPart(string strPart);
        string DisplayProduct();
        void EmptyParts();

    private:
        string m_strFullParts;
    };

    // Base Class
    //////////////////////////////////////////////////////////////////////////
    class AbstractBuilder
    {
    public:
        AbstractBuilder();
        virtual ~AbstractBuilder();

        virtual void BuildHead() = 0;
        virtual void BuildData() = 0;
        virtual void BuildType() = 0;
        virtual void BuildP1P1() = 0;
        virtual void BuildLen() = 0;
        virtual Product* GetProduct() = 0;
    };


    //////////////////////////////////////////////////////////////////////////
    class ConcreteBuilderA : public AbstractBuilder
    {
    public:
        ConcreteBuilderA(Product* pProduct);
        virtual ~ConcreteBuilderA();

        virtual void BuildHead();
        virtual void BuildData();
        virtual void BuildType();
        virtual void BuildP1P1();
        virtual void BuildLen();
        virtual Product* GetProduct();

    private:
        Product* m_pProduct;
    };

    //////////////////////////////////////////////////////////////////////////
    class ConcreteBuilderB : public AbstractBuilder
    {
    public:
        ConcreteBuilderB(Product* pProduct);
        virtual ~ConcreteBuilderB();

        virtual void BuildHead();
        virtual void BuildData();
        virtual void BuildType();
        virtual void BuildP1P1();
        virtual void BuildLen();
        virtual Product* GetProduct();

    private:
        Product* m_pProduct;
    };

    //////////////////////////////////////////////////////////////////////////
    class Director
    {
    public:
        Director(AbstractBuilder* pAbstractBuilder);
        ~Director();
        void Construct1();
        void Construct2();


    private:
        AbstractBuilder* m_pAbstractBuilder;
    };


    //////////////////////////////////////////////////////////////////////////
    void BuilderPattern_Test_A();
    void BuilderPattern_Test_B();

}

#endif

实现
#include "BuilderPattern.h"
#include <iostream>
using namespace std;

namespace BuilderPattern
{

    //////////////////////////////////////////////////////////////////////////
    Product::Product()
    {
    }
    Product::~Product()
    {
    }

    void Product::AddPart(string strPart)
    {
        m_strFullParts += strPart;
    }

    string Product::DisplayProduct()
    {
        cout << m_strFullParts << endl;
        return m_strFullParts;
    }

    void Product::EmptyParts()
    {
        m_strFullParts = "";
    }

    //////////////////////////////////////////////////////////////////////////
    AbstractBuilder::AbstractBuilder()
    {
    }
    AbstractBuilder::~AbstractBuilder()
    {
    }

    //////////////////////////////////////////////////////////////////////////
    ConcreteBuilderA::ConcreteBuilderA(Product* pProduct)
        : m_pProduct(NULL)
    {
        if (pProduct != NULL)
        {
            m_pProduct = pProduct;
        }
    }

    ConcreteBuilderA::~ConcreteBuilderA()
    {
        if (m_pProduct != NULL)
        {
            delete m_pProduct;
            m_pProduct = NULL;
        }
    }

    void ConcreteBuilderA::BuildHead()
    {
        m_pProduct->AddPart("ConcreteBuilderA::BuildHead\n");
    }
    void ConcreteBuilderA::BuildData()
    {
        m_pProduct->AddPart("ConcreteBuilderA::BuildData\n");
    }
    void ConcreteBuilderA::BuildType()
    {
        m_pProduct->AddPart("ConcreteBuilderA::BuildType\n");
    }
    void ConcreteBuilderA::BuildP1P1()
    {
        m_pProduct->AddPart("ConcreteBuilderA::BuildP1P1\n");
    }
    void ConcreteBuilderA::BuildLen()
    {
        m_pProduct->AddPart("ConcreteBuilderA::BuildLen\n");
    }
    Product* ConcreteBuilderA::GetProduct()
    {
        return m_pProduct;
    }


    //////////////////////////////////////////////////////////////////////////
    ConcreteBuilderB::ConcreteBuilderB(Product* pProduct)
        : m_pProduct(NULL)
    {
        if (pProduct != NULL)
        {
            m_pProduct = pProduct;
        }
    }

    ConcreteBuilderB::~ConcreteBuilderB()
    {
        if (m_pProduct != NULL)
        {
            delete m_pProduct;
            m_pProduct = NULL;
        }
    }

    void ConcreteBuilderB::BuildHead()
    {
        m_pProduct->AddPart("ConcreteBuilderB::BuildHea\n");
    }
    void ConcreteBuilderB::BuildData()
    {
        m_pProduct->AddPart("ConcreteBuilderB::BuildData\n");
    }
    void ConcreteBuilderB::BuildType()
    {
        m_pProduct->AddPart("ConcreteBuilderB::BuildType\n");
    }
    void ConcreteBuilderB::BuildP1P1()
    {
        m_pProduct->AddPart("ConcreteBuilderB::BuildP1P1\n");
    }
    void ConcreteBuilderB::BuildLen()
    {
        m_pProduct->AddPart("ConcreteBuilderB::BuildLen\n");
    }
    Product* ConcreteBuilderB::GetProduct()
    {
        return m_pProduct;
    }

    //////////////////////////////////////////////////////////////////////////
    Director::Director(AbstractBuilder* pAbstractBuilder)
        : m_pAbstractBuilder(NULL)
    {
        if (pAbstractBuilder != NULL)
        {
            m_pAbstractBuilder = pAbstractBuilder;
        }
    }
    Director::~Director()
    {
        if (m_pAbstractBuilder != NULL)
        {
            delete m_pAbstractBuilder;
            m_pAbstractBuilder = NULL;
        }
    }
    void Director::Construct1()
    {
        m_pAbstractBuilder->GetProduct()->EmptyParts();

        m_pAbstractBuilder->BuildData();
        m_pAbstractBuilder->BuildType();
        m_pAbstractBuilder->BuildP1P1();
        m_pAbstractBuilder->BuildLen();
        m_pAbstractBuilder->BuildData();

        m_pAbstractBuilder->GetProduct()->DisplayProduct();
    }

    void Director::Construct2()
    {
        m_pAbstractBuilder->GetProduct()->EmptyParts();

        m_pAbstractBuilder->BuildLen();
        m_pAbstractBuilder->BuildData();
        m_pAbstractBuilder->BuildType();
        m_pAbstractBuilder->BuildP1P1();
        m_pAbstractBuilder->BuildData();

        m_pAbstractBuilder->GetProduct()->DisplayProduct();
    }

    //////////////////////////////////////////////////////////////////////////
    void BuilderPattern_Test_A()
    {
        Director* pDirector = new Director(new ConcreteBuilderA(new Product()));

        pDirector->Construct1();
        pDirector->Construct2();

        delete pDirector;
        pDirector = NULL;
    }

    void BuilderPattern_Test_B()
    {
        Director* pDirector = new Director(new ConcreteBuilderB(new Product()));

        pDirector->Construct1();
        pDirector->Construct2();

        delete pDirector;
        pDirector = NULL;
    }
}

客户端
#include "BuilderPattern.h"

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

void main()
{
    BuilderPattern_Test_A();
    BuilderPattern_Test_B();
}

运行结果

猜你喜欢

转载自jacky-dai.iteye.com/blog/2297115