• (创建型模式)Builder——建造者模式(生成器模式)


    1、意图

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

    2、核心思想

         将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。

    即用户就只需要指定需要建造的类型就可以得到产品,而具体的建造过程和细节就不需要知道了。

    建造模式可以强制实行一种分步骤进行的建造过程

    3、优缺点分析

    GOOD:使得建造代码与表示代码分离,由于建造者隐藏了该产品是如何组装的,所以若需要改变一个产品的内部表示,只需要再定义一个具体的建造者就可以了。

    适用于:

    (1)在当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时适用。

    就是说:主要用于创建一些复杂的对象,这些对象内部的构建顺序通常是稳定的,但是对象内部的具体各个构建方法通常面临着复杂的变化。

    (2)当构造过程必须允许被构造的对象有不同的表示时。

    4、标准UML图

    clip_image002

    抽象基类:

    Builder: 这个基类是全部创建对象过程的抽象,提供构建不同组成部分的多个纯虚接口函数BuilderXXX()。

    派生类:

    ConcreteBuilder:是具体的建造者,实现各个Builder接口,构建和装配各个部件。

    聚合类:

    Director:指挥者类,用于构建一个调用Builder接口的对象。

    接口函数:

    1)Builder::BuilderPartA,Builder::BuilderPartB:是对一个对象不同部分的构建函数接口,由Builder的派生类来具体实现。

    2)Director::Construct:通过调用BuilderPartA和BuilderPartB来完成对象的构建,所以各个不同部分装配的过程是一致的(同样调用Construct函数),但是不同的构建方式会有不同的表示(根据Builder的实际类型来决定如何构建,也就是多态)

    5、标准源码

       1: #ifndef BUILDER_H
       2: #define BUILDER_H
       3:  
       4: // 虚拟基类,是所有Builder的基类,提供不同部分的构建接口函数
       5: class Builder
       6: {
       7: public:
       8:     Builder(){};
       9:     virtual ~Builder(){}
      10:  
      11:     // 纯虚函数,提供构建不同部分的构建接口函数
      12:     virtual void BuilderPartA() = 0;
      13:     virtual void BuilderPartB() = 0;
      14: };
      15:  
      16: // 使用Builder构建产品,构建产品的过程都一致,但是不同的builder有不同的实现
      17: // 这个不同的实现通过不同的Builder派生类来实现,存有一个Builder的指针,通过这个来实现多态调用
      18: class Director
      19: {
      20: public:
      21:     Director(Builder* pBuilder);
      22:     ~Director();
      23:  
      24:     void Construct();
      25:  
      26: private:
      27:     Builder* m_pBuilder;
      28: };
      29:  
      30: // Builder的派生类,实现BuilderPartA和BuilderPartB接口函数
      31: class ConcreateBuilder1
      32:     : public Builder
      33: {
      34: public:
      35:     ConcreateBuilder1(){}
      36:     virtual ~ConcreateBuilder1(){}
      37:  
      38:     virtual void BuilderPartA();
      39:     virtual void BuilderPartB();
      40: };
      41:  
      42: // Builder的派生类,实现BuilderPartA和BuilderPartB接口函数
      43: class ConcreateBuilder2
      44:     : public Builder
      45: {
      46: public:
      47:     ConcreateBuilder2(){}
      48:     virtual ~ConcreateBuilder2(){}
      49:  
      50:     virtual void BuilderPartA();
      51:     virtual void BuilderPartB();
      52: };
      53:  
      54: #endif

       1: #include "Builder.h"
       2: #include <iostream>
       3:  
       4: void ConcreateBuilder1::BuilderPartA()
       5: {
       6:     std::cout << "BuilderPartA by ConcreateBuilder1\n";
       7: }
       8:  
       9: void ConcreateBuilder1::BuilderPartB()
      10: {
      11:     std::cout << "BuilderPartB by ConcreateBuilder1\n";
      12: }
      13:  
      14: void ConcreateBuilder2::BuilderPartA()
      15: {
      16:     std::cout << "BuilderPartA by ConcreateBuilder2\n";
      17: }
      18:  
      19: void ConcreateBuilder2::BuilderPartB()
      20: {
      21:     std::cout << "BuilderPartB by ConcreateBuilder2\n";
      22: }
      23:  
      24: Director::Director(Builder* pBuilder)
      25:     : m_pBuilder(pBuilder)
      26: {
      27: }
      28:  
      29: Director::~Director()
      30: {
      31:     delete m_pBuilder;
      32:     m_pBuilder = NULL;
      33: }
      34:  
      35: // Construct函数表示一个对象的整个构建过程,不同的部分之间的装配方式都是一致的,
      36: // 首先构建PartA其次是PartB,只是根据不同的构建者会有不同的表示
      37: void Director::Construct()
      38: {
      39:     m_pBuilder->BuilderPartA();
      40:     m_pBuilder->BuilderPartB();
      41: }

       1: #include "Builder.h"
       2: #include <stdlib.h>
       3:  
       4: int main()
       5: {
       6:     Builder* pBuilder1 = new ConcreateBuilder1;
       7:     Director *pDirector1 = new Director(pBuilder1);
       8:     pDirector1->Construct();
       9:  
      10:     Builder* pBuilder2 = new ConcreateBuilder2;
      11:     Director *pDirector2 = new Director(pBuilder2);
      12:     pDirector2->Construct();
      13:  
      14:     delete pDirector1;
      15:     delete pDirector2;
      16:  
      17:     system("pause");
      18:  
      19:     return 0;
      20: }
  • 相关阅读:
    查找链表中是否有环linked-list-cycle
    reverse-integer
    AVL树之 Java的实现
    single-number
    Best Time to Buy and Sell Stock II
    maximun-depth-of-binary-tree
    minimun-depth-of-binary-tree
    剑指offer--矩阵中的路径
    grep的几个参数
    fsck和badlocks
  • 原文地址:https://www.cnblogs.com/steven_oyj/p/1748791.html
Copyright © 2020-2023  润新知