• C++创建型模式-建造者模式


    1.1 基本概念

    建造者模式(Builder): 将一个复杂对象的构建与它的表示分离,使得同样的构建过程就可以创建不同的表示。

    建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

    什么是复杂对象:建造者模式中,复杂对象是指那些包含多个成员属性的对象,这些成员属性称为部件或零件,比如电子邮件包含发件人、收件人、主题、内容、附件等部件。

    1.2 定义方式

    (1)抽象建造者(Builder)

    抽象建造者为创建一个产品Product对象的各个部件指定抽象接口,该接口一般声明两种方法,一类方法用于创建复杂对象的各个部件,另一类方法用于返回复杂对象。

    (2)具体建造者(ConcreteBuilder)

    具体建造者实现了抽象建造者接口,实现各个部件的构造和装配方法,定义并明确它所创建的复杂对象,也可以提供一个方法返回创建好的复杂产品对象。

    (3)产品角色(Product)

    产品角色是被构建的复杂对象,包含多个组成部件,具体建造者创建该产品的内部表示并定义它的装配过程。

    (4)指挥者(Director)

    指挥者负责安排复杂对象的建造次序,指挥者与抽象建造者之间存在关联关系,可调用建造者对象的部件与装配方法,完成发展对象的建造。客户端一般只需要与指挥者交互。

    1.3 优缺点

    优点:
    (1)将产品本身与产品的创建过程解耦,使相同的创建过程可以创建不同的产品对象;
    (2)增加新的具体建造者无效修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便。
    缺点:
    (1)建造者模式所创建的产品一般具有较多的共同点,产品差异过大,则不适合;
     

    1.4 应用场景

    对象的创建过程独立于创建该对象的类,在建造者模式中引入了指挥者类,将创建过程封装在指挥者类中,而不在建造者类中。
     

    1.5 实现方式

    建造者模式比较简单,主要就是将建造过程与具体表示分离,做到了建造过程的抽象,当有新的对象要创建并且建造过程相同,可以继承建造类实现自己的具体表示即可。

    KFC 套餐实例,套餐是一个复杂的对象,一个套餐包含主食和饮料等组成部分,不用的套餐 主食和饮料的类型不同,服务员可以根据顾客的需求,一步步完成组成套餐。

    通过以上分析,套餐相当于 产品角色,服务员相当于指挥者,不同种类的套餐制作方法称为建造者。

    1. //建造者模式示例代码
    2. #include
    3. using namespace std;
    4. //产品类Meal 为复杂产品对象 有两个属性
    5. class Meal{
    6. private:
    7. std::string food_= "";
    8. std::string drink_ = "";
    9. public:
    10. void setFood(std::string food){
    11. food_= food;
    12. }
    13. std::string getFood(){
    14. return food_;
    15. }
    16. void setDrink(std::string drink){
    17. drink_= drink;
    18. }
    19. std::string getDrink(){
    20. return drink_;
    21. }
    22. };
    23. //抽象建造者
    24. class MealBuilder
    25. {
    26. public:
    27. virtual void buildFood() = 0;
    28. virtual void buildDrink() = 0;
    29. virtual Meal* getMeal()= 0;
    30. // 抽象类构建必须有虚析构函数 以防止内存泄漏
    31. virtual ~MealBuilder(){
    32. cout << "~MealBuilder()" << endl;
    33. }
    34. };
    35. //具体建造者SubMealBuilderA(A套餐建造者)
    36. class SubMealBuilderA :public MealBuilder
    37. {
    38. public:
    39. SubMealBuilderA(){
    40. m_pMeal = new Meal;
    41. }
    42. ~SubMealBuilderA(){
    43. cout << "SubMealBuilderA()" << endl;
    44. }
    45. void buildFood()
    46. {
    47. m_pMeal->setFood("A drumstick burger");
    48. cout << "A drumstick burger" << endl;
    49. }
    50. void buildDrink()
    51. {
    52. m_pMeal->setDrink("A cup of coke");
    53. cout << "A cup of coke" << endl;
    54. }
    55. Meal* getMeal(){
    56. return m_pMeal;
    57. }
    58. private:
    59. Meal* m_pMeal;
    60. };
    61. //具体建造者SubMealBuilderB(B套餐建造者)
    62. class SubMealBuilderB :public MealBuilder
    63. {
    64. private:
    65. MealBuilder *pBuilder;
    66. public:
    67. SubMealBuilderB(){
    68. m_pMeal = new Meal;
    69. }
    70. ~SubMealBuilderB(){
    71. cout << "SubMealBuilderB()" << endl;
    72. }
    73. void buildFood()
    74. {
    75. m_pMeal->setFood("A chicken roll");
    76. cout << "A chicken roll" << endl;
    77. }
    78. void buildDrink()
    79. {
    80. m_pMeal->setDrink("a cup of juice");
    81. cout << "a cup of juice" << endl;
    82. }
    83. private:
    84. Meal* m_pMeal;
    85. };
    86. //指挥者 WaitDirector
    87. class WaitDirector
    88. {
    89. private:
    90. MealBuilder *pBuilder;
    91. public:
    92. void setMealBuilder(MealBuilder *iBuilder)
    93. {
    94. pBuilder = iBuilder;
    95. }
    96. Meal* construct()
    97. {
    98. pBuilder->buildFood();
    99. pBuilder->buildDrink();
    100. return pBuilder->getMeal();
    101. }
    102. };
    103. //客户端调用
    104. int main()
    105. {
    106. //确定套餐的种类
    107. MealBuilder* mb = new SubMealBuilderA();
    108. //服务员指挥者
    109. WaitDirector* waiter = new WaitDirector();
    110. //服务员准备套餐
    111. waiter->setMealBuilder(mb);
    112. //客户获得套餐
    113. waiter->construct();
    114. Meal* meal = mb->getMeal();
    115. meal->getFood();
    116. meal->getDrink();
    117. delete mb;
    118. mb = nullptr;
    119. delete waiter;
    120. mb = waiter;
    121. delete meal;
    122. meal = nullptr;
    123. return 0;
    124. }

    执行结果


    A drumstick burger
    A cup of coke
    SubMealBuilderA()
    ~MealBuilder()
     

    参考文献:

    【1】C++ 设计模式之建造者模式_ACERROR的博客-CSDN博客_c++建造者模式

    【2】C++析构函数为什么要作为虚函数_shuixiaowei0530的博客-CSDN博客 

  • 相关阅读:
    java-net-php-python-springboot基于SpringBoot的OA办公管理系统计算机毕业设计程序
    【无标题】
    python-数据分析-numpy、pandas、matplotlib的常用方法
    从菜鸟到大师:编程必须遵循的三个基本原则
    力扣27-移除元素——简单题
    Android基础(四):TCP/IP
    单节点高并发Linux服务器影响接入能力的因素有哪些
    深度探索:智能家居背后的科技力量与伦理思考
    Linux下Socket编程
    Android 多渠道配置
  • 原文地址:https://blog.csdn.net/kenjianqi1647/article/details/123626593