在实际的项目中,很多时候我们和一些设备的沟通都是通过数据流来完成的。用户和设备通过固定格式的包进行处理。实际项目
中使用的一个实例如下: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(); }
运行结果