每天一个设计模式之生成器模式 Qt系列教程

  • A+
所属分类:Qt系列教程

介绍

每天一个设计模式之生成器模式  Qt系列教程

核心是对象的组成和装配方式须分离

示例

场景:有一份数据,数据需要按照文件头、文件体、文件尾的格式导出,可以选择以文本、xml等格式导出。

接口图

每天一个设计模式之生成器模式  Qt系列教程

Director(指导类)用于控制产品的生成过程,Director的控制对象是Builder。在本场景中,负责整体的构建算法,不变的部分,即数据导出规则(即需要按照文件头、文件体、文件尾的格式导出),这部分是可以复用的,不论是用文本格式还是xml格式导出,都必须遵循该规则。

Builder负责变化的部分,是各种生成器。在本场景中指的是以文本/xml方式导出的生成器,不同的存储方式导致生成器在生成文件头、文件体、文件尾的格式不同,每个生成器的内部实现都不同。各个生成器还可以继续抽象出一个接口类,将共同的接口提取到上层接口中,便于在Director中装配。

代码

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. #include <sstream>
  5. using namespace  std;
  6. //模板函数,不同类型的形参输入,都可以套用此函数体
  7. template<class T>
  8. string ConvertToString(T value)
  9. {
  10.     stringstream ss;
  11.     ss<<value;
  12.     return ss.str();
  13. }
  14. //文件头数据存储类
  15. class ExportHeaderModel{
  16. public:
  17.     ExportHeaderModel(string strDepId, string strExportDate)
  18.         :m_strDepId(strDepId)
  19.         ,m_strExportDate(strExportDate)
  20.     {
  21.     }
  22.     string getDepId()
  23.     {
  24.         return m_strDepId;
  25.     }
  26.     string getExportDate()
  27.     {
  28.         return m_strExportDate;
  29.     }
  30. private:
  31.     string m_strDepId;//对账单的部门id
  32.     string m_strExportDate;//对账单的导出日期
  33. };
  34. //文件体数据存储类
  35. class ExportDataModel{
  36. public:
  37.     ExportDataModel(string strTransId, double Quantity)
  38.         :m_strTransId(strTransId)
  39.         ,m_Quantity(Quantity)
  40.     {
  41.     }
  42.     string getstrTransId()
  43.     {
  44.         return m_strTransId;
  45.     }
  46.     double getQuantity()
  47.     {
  48.         return m_Quantity;
  49.     }
  50. private:
  51.     string m_strTransId;//交易Id
  52.     double m_Quantity;
  53. };
  54. //文件尾数据存储类
  55. class ExportFooterModel{
  56. public:
  57.     ExportFooterModel(string exportUser):m_exportUser(exportUser)
  58.     {
  59.     }
  60.     string getexportUser()
  61.     {
  62.         return m_exportUser;
  63.     }
  64. private:
  65.     string m_exportUser;
  66. };
  67. //生成器抽象类,抽象了构造的各个步骤
  68. class Builder{
  69. public:
  70.     virtual void builderHeader(ExportHeaderModel& ehm) =0;
  71.     //考虑到我们在一个对这张周期,可能有多笔的交易记录(文件体对象由多个),我们用vector
  72.     virtual void builderBody(vector<ExportDataModel*>& edmCollection) =0;
  73.     virtual void builderFoot(ExportFooterModel& efm) =0;
  74.     virtual string getResult() =0;
  75. protected:
  76.     Builder(){
  77.     }
  78. };
  79. //导出文本格式的生成器,负责文件形式的构造实现
  80. class TxtBuilder:public Builder{
  81. private:
  82.     string m_strResult;
  83.     // Builder interface
  84. public:
  85.     TxtBuilder()
  86.     {
  87.         m_strResult="";
  88.     }
  89.     void builderHeader(ExportHeaderModel &ehm){
  90.         m_strResult = "--txt---\n";
  91.         m_strResult += ehm.getDepId()+","+ehm.getExportDate()+"\n";
  92.     }
  93.     void builderBody(std::vector<ExportDataModel *> &edmCollection)
  94.     {
  95.         for(vector<ExportDataModel*>::iterator iter = edmCollection.begin();iter!=edmCollection.end();iter++)
  96.         {
  97.             m_strResult+=(*iter)->getstrTransId()+":"+ConvertToString((*iter)->getQuantity())+"\n";
  98.         }
  99.     }
  100.     void builderFoot(ExportFooterModel &efm)
  101.     {
  102.         m_strResult += efm.getexportUser()+"\n";
  103.     }
  104.     string getResult()
  105.     {
  106.         return m_strResult;
  107.     }
  108. };
  109. //导出xml格式的生成器,负责xml形式的构造实现
  110. class XmlBuilder:public Builder{
  111. private:
  112.     string m_strResult;
  113.     // Builder interface
  114. public:
  115.     XmlBuilder()
  116.     {
  117.         m_strResult="";
  118.     }
  119.     void builderHeader(ExportHeaderModel &ehm){
  120.         m_strResult = "--xml---\n";
  121.         m_strResult += ehm.getDepId()+","+ehm.getExportDate()+"\n";
  122.     }
  123.     void builderBody(std::vector<ExportDataModel *> &edmCollection)
  124.     {
  125.         for(vector<ExportDataModel*>::iterator iter = edmCollection.begin();iter!=edmCollection.end();iter++)
  126.         {
  127.             m_strResult+=(*iter)->getstrTransId()+":"+ConvertToString((*iter)->getQuantity())+"\n";
  128.         }
  129.     }
  130.     void builderFoot(ExportFooterModel &efm)
  131.     {
  132.         m_strResult += efm.getexportUser()+"\n";
  133.     }
  134.     string getResult()
  135.     {
  136.         return m_strResult;
  137.     }
  138. };
  139. //负责构建算法的类,这部分是固定的,可以复用的
  140. class Director{
  141. public:
  142.     Director(Builder* builder):m_pBuilder(builder){}
  143.     void construct(ExportHeaderModel& ehm, vector<ExportDataModel*>& edmCollection, ExportFooterModel& efm)
  144.     {
  145.         m_pBuilder->builderHeader(ehm);
  146.         m_pBuilder->builderBody(edmCollection);
  147.         m_pBuilder->builderFoot(efm);
  148.     }
  149. private:
  150.     Builder* m_pBuilder;
  151. };
  152. int main(void)
  153. {
  154.     ExportHeaderModel* pEhm = new ExportHeaderModel("nanjing","6.1");
  155.     ExportDataModel* pEdm = new ExportDataModel("1",10000.00);
  156.     ExportDataModel* pEdm2 = new ExportDataModel("2",20000.00);
  157.     vector<ExportDataModel*> myVec;
  158.     myVec.push_back(pEdm);
  159.     myVec.push_back(pEdm2);
  160.     ExportFooterModel* pEfm = new ExportFooterModel("lgw");
  161.     Builder* pBuilder = new XmlBuilder();
  162. //    Builder* pBuilder = new TxtBuilder();//Director通过装配不同的生成器,来生产不同形式的输出
  163.     Director* pDirector = new Director(pBuilder);
  164.     pDirector->construct(*pEhm,myVec,*pEfm);
  165.     cout<<pBuilder->getResult()<<endl;
  166.     return 0;
  167. }
Qt大课堂-QtShare

发表评论

您必须登录才能发表评论!