- A+
所属分类:Qt系列教程
介绍
核心是对象的组成和装配方式须分离
示例
场景:有一份数据,数据需要按照文件头、文件体、文件尾的格式导出,可以选择以文本、xml等格式导出。
接口图
Director(指导类)用于控制产品的生成过程,Director的控制对象是Builder。在本场景中,负责整体的构建算法,不变的部分,即数据导出规则(即需要按照文件头、文件体、文件尾的格式导出),这部分是可以复用的,不论是用文本格式还是xml格式导出,都必须遵循该规则。
Builder负责变化的部分,是各种生成器。在本场景中指的是以文本/xml方式导出的生成器,不同的存储方式导致生成器在生成文件头、文件体、文件尾的格式不同,每个生成器的内部实现都不同。各个生成器还可以继续抽象出一个接口类,将共同的接口提取到上层接口中,便于在Director中装配。
代码
- #include <iostream>
- #include <string>
- #include <vector>
- #include <sstream>
- using namespace std;
- //模板函数,不同类型的形参输入,都可以套用此函数体
- template<class T>
- string ConvertToString(T value)
- {
- stringstream ss;
- ss<<value;
- return ss.str();
- }
- //文件头数据存储类
- class ExportHeaderModel{
- public:
- ExportHeaderModel(string strDepId, string strExportDate)
- :m_strDepId(strDepId)
- ,m_strExportDate(strExportDate)
- {
- }
- string getDepId()
- {
- return m_strDepId;
- }
- string getExportDate()
- {
- return m_strExportDate;
- }
- private:
- string m_strDepId;//对账单的部门id
- string m_strExportDate;//对账单的导出日期
- };
- //文件体数据存储类
- class ExportDataModel{
- public:
- ExportDataModel(string strTransId, double Quantity)
- :m_strTransId(strTransId)
- ,m_Quantity(Quantity)
- {
- }
- string getstrTransId()
- {
- return m_strTransId;
- }
- double getQuantity()
- {
- return m_Quantity;
- }
- private:
- string m_strTransId;//交易Id
- double m_Quantity;
- };
- //文件尾数据存储类
- class ExportFooterModel{
- public:
- ExportFooterModel(string exportUser):m_exportUser(exportUser)
- {
- }
- string getexportUser()
- {
- return m_exportUser;
- }
- private:
- string m_exportUser;
- };
- //生成器抽象类,抽象了构造的各个步骤
- class Builder{
- public:
- virtual void builderHeader(ExportHeaderModel& ehm) =0;
- //考虑到我们在一个对这张周期,可能有多笔的交易记录(文件体对象由多个),我们用vector
- virtual void builderBody(vector<ExportDataModel*>& edmCollection) =0;
- virtual void builderFoot(ExportFooterModel& efm) =0;
- virtual string getResult() =0;
- protected:
- Builder(){
- }
- };
- //导出文本格式的生成器,负责文件形式的构造实现
- class TxtBuilder:public Builder{
- private:
- string m_strResult;
- // Builder interface
- public:
- TxtBuilder()
- {
- m_strResult="";
- }
- void builderHeader(ExportHeaderModel &ehm){
- m_strResult = "--txt---\n";
- m_strResult += ehm.getDepId()+","+ehm.getExportDate()+"\n";
- }
- void builderBody(std::vector<ExportDataModel *> &edmCollection)
- {
- for(vector<ExportDataModel*>::iterator iter = edmCollection.begin();iter!=edmCollection.end();iter++)
- {
- m_strResult+=(*iter)->getstrTransId()+":"+ConvertToString((*iter)->getQuantity())+"\n";
- }
- }
- void builderFoot(ExportFooterModel &efm)
- {
- m_strResult += efm.getexportUser()+"\n";
- }
- string getResult()
- {
- return m_strResult;
- }
- };
- //导出xml格式的生成器,负责xml形式的构造实现
- class XmlBuilder:public Builder{
- private:
- string m_strResult;
- // Builder interface
- public:
- XmlBuilder()
- {
- m_strResult="";
- }
- void builderHeader(ExportHeaderModel &ehm){
- m_strResult = "--xml---\n";
- m_strResult += ehm.getDepId()+","+ehm.getExportDate()+"\n";
- }
- void builderBody(std::vector<ExportDataModel *> &edmCollection)
- {
- for(vector<ExportDataModel*>::iterator iter = edmCollection.begin();iter!=edmCollection.end();iter++)
- {
- m_strResult+=(*iter)->getstrTransId()+":"+ConvertToString((*iter)->getQuantity())+"\n";
- }
- }
- void builderFoot(ExportFooterModel &efm)
- {
- m_strResult += efm.getexportUser()+"\n";
- }
- string getResult()
- {
- return m_strResult;
- }
- };
- //负责构建算法的类,这部分是固定的,可以复用的
- class Director{
- public:
- Director(Builder* builder):m_pBuilder(builder){}
- void construct(ExportHeaderModel& ehm, vector<ExportDataModel*>& edmCollection, ExportFooterModel& efm)
- {
- m_pBuilder->builderHeader(ehm);
- m_pBuilder->builderBody(edmCollection);
- m_pBuilder->builderFoot(efm);
- }
- private:
- Builder* m_pBuilder;
- };
- int main(void)
- {
- ExportHeaderModel* pEhm = new ExportHeaderModel("nanjing","6.1");
- ExportDataModel* pEdm = new ExportDataModel("1",10000.00);
- ExportDataModel* pEdm2 = new ExportDataModel("2",20000.00);
- vector<ExportDataModel*> myVec;
- myVec.push_back(pEdm);
- myVec.push_back(pEdm2);
- ExportFooterModel* pEfm = new ExportFooterModel("lgw");
- Builder* pBuilder = new XmlBuilder();
- // Builder* pBuilder = new TxtBuilder();//Director通过装配不同的生成器,来生产不同形式的输出
- Director* pDirector = new Director(pBuilder);
- pDirector->construct(*pEhm,myVec,*pEfm);
- cout<<pBuilder->getResult()<<endl;
- return 0;
- }