• 建造者模式 创建型模式之三


    1.组成结构

            想要搞清楚建造者模式,首先先要了解建造者模式种四个角色的定位

    1. Product:表示被构造的复杂对象,就是我们要建造的东西,比如我们要做一个手机,手机就是product。
    2. Builder:建造者,这里需要着重理解的是它是一个抽象类,不负责具体的实现。沿用做手机的例子,上面说了product是手机,那么没有说这是什么类型的手机,比如华为它可以是mate40,也可以是mate50,或者mate60。用一个抽象类就可以统一一个接口,所有的手机都用这个Builder去造。总而言之,主要是为了统一抽象接口。
    3. ConcreteBuilder:这具体的建造者,造mate40的方法肯定不能完全适配mate60或者50。这个具体的建造方法一般会存在多个,它赋值具体的型号制造。
    4. Director:我有时候在疑惑为什么Director的功能不能在builder里完成,为啥非要单独拎出来。后来我想清楚了一件事情,就是builder它不提供建造流程,而只提供建造零件本身,比如做电脑。builder或者ConcreteBuilder它内部只存在BuildDisplay、BuildHost、BuildKeyBoard这种基本的建造功能,但是建造的先后顺序它是不管的。这时候就需要Director来对这个流程进行指挥,先做什么后做什么。而且不同的指挥者,建造的顺序和方式可以能不一样,这就很灵活。如果想要使用新的流程,只需要把director换掉,而不影响builder本身。ConcreteBuilder也可以去增加更多具体的产品的生产方式。

    2.优缺点

    优点

    1. 建造者独立,易扩展。将复杂产品的构建过程封装分解在不同的方法中,使得创建过程非常清晰,能够让我们更加精确的控制复杂产品对象的创建过程。
    2. 便于控制细节风险。它隔离了复杂产品对象的创建和使用,使得相同的创建过程能够创建不同的产品。

    缺点

    但是也能感受到它的缺点,我们要扩展ConcreteBuilder,前提是什么?它必须具备和其它产品的共同点,甚至要有非常多的共同点。至少流程必须类似。比如这个Builder能制造计算机,对于手机那就可能做不了了。

    1. 产品必须有共同点,范围有限制。
    2. 如内部变化复杂,会有很多的建造类,导致系统庞大。

    3.应用场景

    1. 需要生成的对象具有复杂的内部结构。
    2. 需要生成的对象内部属性本身相互依赖。
    3. 共用Builder的各个ConcreteBuilder需要具备足够的共同点。

    4.示例代码

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. /*
    6. 建造者模式
    7. 组装电脑:显示器 主机 键盘 鼠标
    8. */
    9. /*
    10. 1. 抽象产品类
    11. */
    12. class AbstractProduct
    13. {
    14. public:
    15. virtual ~AbstractProduct() {}
    16. virtual void setDisplay(string display) = 0;
    17. virtual void setHost(string host) = 0;
    18. virtual void setKeyBoard(string KeyBoard) = 0;
    19. virtual void setMouse(string mouse) = 0;
    20. virtual void show() = 0;
    21. };
    22. /*
    23. 2. 具体产品类
    24. */
    25. class Computer :public AbstractProduct
    26. {
    27. public:
    28. ~Computer() {}
    29. void setDisplay(string display)
    30. {
    31. m_vec.emplace_back(display);
    32. }
    33. void setHost(string host)
    34. {
    35. m_vec.emplace_back(host);
    36. }
    37. void setKeyBoard(string KeyBoard)
    38. {
    39. m_vec.emplace_back(KeyBoard);
    40. }
    41. void setMouse(string mouse)
    42. {
    43. m_vec.emplace_back(mouse);
    44. }
    45. void show()
    46. {
    47. cout << "----------组装电脑---------" << endl;
    48. for (auto& x : m_vec)
    49. {
    50. cout << x << endl;
    51. }
    52. }
    53. private:
    54. vector m_vec;
    55. };
    56. /*
    57. 3. 抽象建造者
    58. */
    59. class AbstractBuilder
    60. {
    61. public:
    62. //创建电脑产品
    63. AbstractBuilder()
    64. :product(new Computer) {}
    65. virtual ~AbstractBuilder() {}
    66. //抽象电脑产品创建的统一抽象接口
    67. virtual void BuildDisplay(string display) = 0;
    68. virtual void BuildHost(string host) = 0;
    69. virtual void BuildKeyBoard(string KeyBoard) = 0;
    70. virtual void BuildMouse(string mouse) = 0;
    71. AbstractProduct* getProduct()
    72. {
    73. return product;
    74. }
    75. protected:
    76. AbstractProduct* product;
    77. };
    78. /*
    79. 4. 具体建造者:具体实现抽象建造者各个部件的接口
    80. */
    81. class ComputerBuilder :public AbstractBuilder
    82. {
    83. public:
    84. ~ComputerBuilder() {}
    85. void BuildDisplay(string display)
    86. {
    87. product->setDisplay(display);
    88. }
    89. void BuildHost(string host)
    90. {
    91. product->setHost(host);
    92. }
    93. void BuildKeyBoard(string KeyBoard)
    94. {
    95. product->setKeyBoard(KeyBoard);
    96. }
    97. void BuildMouse(string mouse)
    98. {
    99. product->setMouse(mouse);
    100. }
    101. };
    102. /*
    103. 5. 指挥者:安排和调度复杂对象的创建过程
    104. */
    105. class Director
    106. {
    107. public:
    108. Director(AbstractBuilder* builder)
    109. :m_builder(builder) {}
    110. ~Director() {}
    111. AbstractProduct* createComputer(string display, string host, string KeyBoard, string mouse)
    112. {
    113. m_builder->BuildDisplay(display);
    114. m_builder->BuildHost(host);
    115. m_builder->BuildKeyBoard(KeyBoard);
    116. m_builder->BuildMouse(mouse);
    117. return m_builder->getProduct();
    118. }
    119. private:
    120. AbstractBuilder* m_builder;
    121. };
    122. int main()
    123. {
    124. //1. 创建电脑建造者
    125. AbstractBuilder* Computer_Builder = new ComputerBuilder;
    126. //2. 创建电脑建造者的 管理者
    127. Director* pDcomp = new Director(Computer_Builder);
    128. //3. 管理者指挥 建造者制造电脑产品
    129. AbstractProduct* computerPro = pDcomp->createComputer("联想显示器", "外星人主机", "雷蛇键盘", "罗技鼠标");
    130. //4. 电脑产品制造完成
    131. computerPro->show();
    132. //别忘了释放内存
    133. delete Computer_Builder;
    134. delete pDcomp;
    135. delete computerPro;
    136. return 0;
    137. }

    5.引用

    2.5 万字详解:23 种设计模式 - 知乎 (zhihu.com)

    C++设计模式:建造者模式(详解+案例代码)_Yuleo_的博客-CSDN博客

     

  • 相关阅读:
    一直出现问题,发现服务器磁盘空间已满导致,腾出服务器磁盘空间命令
    运行disco项目报错及解决
    ToBeWritten之记录狩猎过程
    算法27:最长公共子序列——样本模型(4)
    Leetcode - 112双周赛
    MMKV(2)
    【Kotlin】函数
    哈工大李治军老师操作系统笔记【6】:CPU管理的直观想法(Learning OS Concepts By Coding Them !)
    win10+GTX1050+pytorch安装
    【LeetCode选讲·第五期】「盛最多水的容器」「有效的括号」
  • 原文地址:https://blog.csdn.net/Physics_ITBoy/article/details/133279115