• C++设计模式-创建型设计模式:构建者(Builder)


    目录

    Builder构建者模式:场景、功能、组成部分

    场景

    功能

    组成部分:Builer+Director


    Builder构建者模式:场景、功能、组成部分

    场景

     还是老套路,首先不用设计模式来实现这个功能:

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. template<class T>
    7. string ConvertToString(T value) {
    8. stringstream ss;
    9. ss << value;
    10. return ss.str();
    11. }
    12. class ExportHeaderModel {
    13. public:
    14. ExportHeaderModel(string strDepId, string strExportDate)
    15. :m_strDepId(strDepId), m_strExportDate(strExportDate)
    16. {}
    17. string getStrDepId() {
    18. return m_strDepId;
    19. }
    20. string getStrExportDate() {
    21. return m_strExportDate;
    22. }
    23. private:
    24. string m_strDepId;//对账单的部门id
    25. string m_strExportDate;//对账单的导出日期
    26. };
    27. class ExportDataModel {
    28. public:
    29. ExportDataModel(string strTransId,double Quantity)
    30. :m_strTransId(strTransId), m_Quantity(Quantity)
    31. {}
    32. string getStrTransId() { return m_strTransId; }
    33. double getQuantity() { return m_Quantity; }
    34. private:
    35. string m_strTransId;//交易ID
    36. double m_Quantity;
    37. };
    38. class ExportFooterModel {
    39. public:
    40. ExportFooterModel(string exportUser)
    41. :m_exportUser(exportUser)
    42. {}
    43. string getExportUser() {
    44. return m_exportUser;
    45. }
    46. private:
    47. string m_exportUser;
    48. };
    49. //考虑一个周期,有多笔交易记录
    50. class ExportToTextHelper {
    51. public:
    52. void doExport(ExportHeaderModel& ehm, vectoredmCollection, ExportFooterModel& efm) {
    53. string strTemp = "";
    54. //第一步:写文件头
    55. strTemp += ehm.getStrDepId() + "," + ehm.getStrExportDate() + "\n";
    56. //第二部:写文件体数据
    57. for (auto it = edmCollection.begin(); it != edmCollection.end(); it++) {
    58. strTemp += (*it)->getStrTransId() + ":" + ConvertToString((*it)->getQuantity()) + "\n";
    59. }
    60. //第三步:拼接文件尾
    61. strTemp += efm.getExportUser() + "\n";
    62. cout << strTemp << endl;
    63. }
    64. };
    65. class ExportToXmlHelper {
    66. public:
    67. void doExport(ExportHeaderModel& ehm, vectoredmCollection, ExportFooterModel& efm) {
    68. string strTemp = "";
    69. //第一步:拼接文件头
    70. strTemp.append("\n ");
    71. strTemp.append("\n");
    72. strTemp.append("
      \n");
    73. strTemp.append(" ");
    74. strTemp.append(ehm.getStrDepId() + "\n");
    75. strTemp.append(" " + ehm.getStrExportDate() + "\n");
    76. strTemp.append(" \n");
    77. //第二部:构建数据体
    78. strTemp.append(" \n");
    79. for (auto it = edmCollection.begin(); it != edmCollection.end(); it++) {
    80. strTemp.append(" " + (*it)->getStrTransId() + "\n");
    81. strTemp.append(" " + ConvertToString((*it)->getQuantity()) + "\n");
    82. }
    83. strTemp.append(" \n");
    84. //第三步:拼接文件尾
    85. strTemp.append("
      \n");
    86. strTemp.append(" " + efm.getExportUser() + "\n");
    87. strTemp.append(" \n\n");
    88. cout << strTemp << endl;
    89. }
    90. };
    91. int main() {
    92. ExportHeaderModel* pEhm = new ExportHeaderModel("南京1支行", "1st June");
    93. ExportDataModel* pEdm1 = new ExportDataModel("1", 10000.0f);
    94. ExportDataModel* pEdm2 = new ExportDataModel("2", 20000.0f);
    95. vectorVec;
    96. Vec.push_back(pEdm1);
    97. Vec.push_back(pEdm2);
    98. ExportFooterModel* pEfm = new ExportFooterModel("yxh");
    99. ExportToTextHelper helper1;
    100. helper1.doExport(*pEhm, Vec, *pEfm);
    101. ExportToXmlHelper helper2;
    102. helper2.doExport(*pEhm, Vec, *pEfm);
    103. return 0;
    104. }

    不错,但有一个问题,两种Helper中都存在着相同的步骤一二三。

    既然都学了设计模式了,这种重复性的代码必然是不符合高逼格的,肯定要重构!

    这里就引出了Builder模式

    1. #include
    2. #include
    3. #include
    4. #include
    5. using namespace std;
    6. template<class T>
    7. string ConvertToString(T value) {
    8. stringstream ss;
    9. ss << value;
    10. return ss.str();
    11. }
    12. class ExportHeaderModel {
    13. public:
    14. ExportHeaderModel(string strDepId, string strExportDate)
    15. :m_strDepId(strDepId), m_strExportDate(strExportDate)
    16. {}
    17. string getStrDepId() {
    18. return m_strDepId;
    19. }
    20. string getStrExportDate() {
    21. return m_strExportDate;
    22. }
    23. private:
    24. string m_strDepId;//对账单的部门id
    25. string m_strExportDate;//对账单的导出日期
    26. };
    27. class ExportDataModel {
    28. public:
    29. ExportDataModel(string strTransId, double Quantity)
    30. :m_strTransId(strTransId), m_Quantity(Quantity)
    31. {}
    32. string getStrTransId() { return m_strTransId; }
    33. double getQuantity() { return m_Quantity; }
    34. private:
    35. string m_strTransId;//交易ID
    36. double m_Quantity;
    37. };
    38. class ExportFooterModel {
    39. public:
    40. ExportFooterModel(string exportUser)
    41. :m_exportUser(exportUser)
    42. {}
    43. string getExportUser() {
    44. return m_exportUser;
    45. }
    46. private:
    47. string m_exportUser;
    48. };
    49. //创建者模式
    50. class Builder {
    51. public:
    52. virtual void builderHeader(ExportHeaderModel& ehm) = 0;
    53. virtual void builderBody(vector& edmCollection) = 0;
    54. virtual void builderFoot(ExportFooterModel& efm) = 0;
    55. virtual string getResult() = 0;
    56. protected:
    57. Builder() {}
    58. };
    59. class TextBuilder :public Builder {
    60. public:
    61. void builderHeader(ExportHeaderModel& ehm) {
    62. m_strResult.append(ehm.getStrDepId() + "," + ehm.getStrExportDate() + "\n");
    63. }
    64. void builderBody(vector& edmCollection) {
    65. for (auto it = edmCollection.begin(); it != edmCollection.end(); it++) {
    66. m_strResult += (*it)->getStrTransId() + ":" + ConvertToString((*it)->getQuantity()) + "\n";
    67. }
    68. }
    69. void builderFoot(ExportFooterModel& efm) {
    70. m_strResult += efm.getExportUser() + "\n";
    71. }
    72. string getResult() {
    73. return m_strResult;
    74. }
    75. public:
    76. TextBuilder() { m_strResult = ""; }
    77. private:
    78. string m_strResult;
    79. };
    80. class Director {
    81. public:
    82. Director(Builder* pBuilder) :m_pBuilder(pBuilder) {}
    83. void construct(ExportHeaderModel& ehm, vectoredmCollection, ExportFooterModel& efm) {
    84. m_pBuilder->builderHeader(ehm);
    85. m_pBuilder->builderBody(edmCollection);
    86. m_pBuilder->builderFoot(efm);
    87. }
    88. private:
    89. Builder* m_pBuilder;
    90. };
    91. int main() {
    92. ExportHeaderModel* pEhm = new ExportHeaderModel("南京1支行", "1st June");
    93. ExportDataModel* pEdm1 = new ExportDataModel("1", 10000.0f);
    94. ExportDataModel* pEdm2 = new ExportDataModel("2", 20000.0f);
    95. vectorVec;
    96. Vec.push_back(pEdm1);
    97. Vec.push_back(pEdm2);
    98. ExportFooterModel* pEfm = new ExportFooterModel("yxh");
    99. Builder* pBuilder = new TextBuilder();
    100. Director* pDirector = new Director(pBuilder);
    101. pDirector->construct(*pEhm, Vec, *pEfm);
    102. cout << pBuilder->getResult() << endl;
    103. return 0;
    104. }

    这里只重构了Text的创建。

    其实总体看来,设计模式的目的就是:把不变的给客户,把以后可能变化的留给开发者,并且要便于开发者增加功能模块,要达到模块于模块之间的松耦合。

    功能

    • 构建复杂产品,而且是细化的,分步骤的构建产品,重在解决一步一步构造复杂对象的问题
    • 这个构建过程是统一的,固定不变的,变化的部分就放到生成器Builder中
    • 只要配置不同的Builder,那么同样的构建过程,就能构建出不同的产品出来

    组成部分:Builer+Director

    • Builder接口,定义如何构建各个部件,每个部件功能如何实现,如何装配这些部件到产品中去
    • Director,定义如何组合来构建产品,负责整体的构建算法,通常分步骤来执行

  • 相关阅读:
    spring ioc的循环依赖问题
    自己编写cmake config.cmake
    RabbitMQ(原理,下载,安装)
    Python实现压缩和解压缩
    Spring Boot_1【配置环境&&项目结构&&Spring Security相关】
    Visual Studio自定义模板参数、备注
    论文阅读--深度学习基础文献
    大数据存储架构详解:数据仓库、数据集市、数据湖、数据网格、湖仓一体
    【Spring】Bean 的作用域和生命周期
    mfc140u.dll丢失怎么修复?4种亲测有效的方法分享
  • 原文地址:https://blog.csdn.net/Jason6620/article/details/126111580