zoukankan      html  css  js  c++  java
  • 【创建型】Builder模式

        生成器模式的主要思想:将产品对象的创建与表现分离开,并且同样的创建过程可以有不同的产品表现。

        直白一点可以理解为:待创建的对象是复杂的,一般情况下是需要经过多个步骤的创建后,最终才能将完整产品创建好,而且每个步骤所创建的都只是产品的一部分而已。这一切的创建步骤,由统一的执导者来完成,称之为:Director(即:导演)。而产品以及组成产品的各个部分的生成细节,由生成器(或者称之为创建者、构建者也行)来完成,称之为:Builder。因此,类关系图参考如下:

        由图可知,对Client来说,同样的执导者,是可以生成不同的产品的,并且最重要的是这一切的构建过程,对它来说是完全透明的,其实它也完全不关心(也不需要关心)产品是如何创建出来的,他只要结果(即:产品)。因此,Client想要什么样的产品,只需要使用相应的生成器去构建即可,仅此而已。

        关于该模式的协作图参考如下:

        由协作图可清晰看出Client、Director、Builder之前的协作关系。模式的编码结构参考如下:

     1 namespace builder
     2 {
     3     // -------- 产品 --------
     4     class Product1 {};
     5     class Product2 {};
     6 
     7     // -------- 生成器 --------
     8     class Builder
     9     {
    10     public:
    11         virtual void buildPartA() { /*some code here........*/ }
    12         virtual void buildPartB() { /*some code here........*/ }
    13         virtual void buildPartC() { /*some code here........*/ }
    14         // ........
    15         virtual void buildPartN() { /*some code here........*/ }
    16 
    17     };//class Builder
    18     class ConcreteBuilder1 : public Builder
    19     {
    20     public:
    21         virtual void buildPartA() { /*some code here........*/ }
    22         virtual void buildPartC() { /*some code here........*/ }
    23         virtual void buildPartE() { /*some code here........*/ }
    24         // ........
    25 
    26         Product1* getProduct1() { return m_pProduct1; }
    27 
    28     private:
    29         Product1* m_pProduct1;
    30 
    31     };//class ConcreteBuilder1
    32     class ConcreteBuilder2 : public Builder
    33     {
    34     public:
    35         virtual void buildPartB() { /*some code here........*/ }
    36         virtual void buildPartC() { /*some code here........*/ }
    37         virtual void buildPartD() { /*some code here........*/ }
    38         // ........
    39 
    40         Product2* getProduct1() { return m_pProduct2; }
    41 
    42     private:
    43         Product2* m_pProduct2;
    44 
    45     };//class ConcreteBuilder2
    46 
    47     // -------- 导演 --------
    48     class Director
    49     {
    50     public:
    51         void construct() {
    52             auto pBuilder = this->getBuilder();
    53             if (nullptr == pBuilder) {
    54                 return;
    55             }
    56             pBuilder->buildPartA();
    57             pBuilder->buildPartB();
    58             pBuilder->buildPartC();
    59             // ........
    60             pBuilder->buildPartN();
    61         }
    62 
    63         void setBuilder(Builder* pBuilder) { m_pBuilder = pBuilder; }
    64 
    65     private:
    66         Builder* getBuilder() { return m_pBuilder; }
    67 
    68     private:
    69         Builder* m_pBuilder;
    70 
    71     };//class Director
    72 
    73     // -------- 客户 --------
    74     class Client
    75     {
    76     public:
    77         void test() {
    78             auto pBuilder = new (std::nothrow) ConcreteBuilder1();
    79             auto pDirector = new (std::nothrow) Director();
    80             if (nullptr == pBuilder || nullptr == pDirector) {
    81                 // some code like below.
    82                 //SAFE_DELETE(pBuilder);
    83                 //SAFE_DELETE(pDirector);
    84                 return;
    85             }
    86             pDirector->setBuilder(pBuilder);
    87             pDirector->construct();
    88             auto pMyProduct = pBuilder->getProduct1();
    89             // some other code here........
    90         }
    91 
    92     };//class Client
    93 
    94 }//namespace builder
    生成器模式编码结构参考

        下在举一个例子说明一下该模式,个人认为,该例子对于该模式的诠释比许多书本上的例子都更好、更加的形象:

        一个人想要建一栋房子,于是他出钱找到了一个施工队,谈好价钱后,施工队就开始可行性分析、绘制图纸........,最后一切准备就序,此时施工队的项目主管就到现场“指手划脚”了,第一天让xxx工人去挖地基;第二天让yyy去布钢筋浇水泥;第三天........;最后房子的所有结构全部完成,房子建好了。于是房子的主人就过来验收了。

        这里出钱的人就是 Client,施工队的主管就是 Director,施工队中的施工班子(就是那些辛辛苦苦的农民工、打工仔等)就是 Builder。

        还有,突然有一天,该出钱的人,觉得这房子住腻了,想重新整整。很简单,他再出钱,重新再去找一个施工队即可。因为前后找的是不同的施工队,前一个建出来的房子是中式风格,现在找的施工队要求是建成欧式风格的。因此,最终建出来的房子,就肯定不一样了。

        a) 这一切,对于出钱的人来说,房子是怎么建成的,他不关心,他只关心最终的产品是他想要的即可。他不会产心这房子是先打地基的,还是先浇水泥的。

        b) 施工班子,这些人,每个人都有他们自己的岗位职责,有的是砌墙的、有的是挖土的、有的是搬石头的、........、有的是测量的,等等。这些人什么时候出班,谁先做好后,后面其他职责的人才可以上场做下一环节的工作等等等等,这些全都是要听主管的。(要不实际工程项目中,出一点差错,都是好多钱钱,这些人赔不起的)。

        c) 主管,对他来说,不同的主管其实完全可以使用完全一样的工序来“指手划脚”的。当然,个人认为,设计模式我们学的是思想,并不能死板地学。该模式的定义中是说:Builder可以换,那试想下,我们Director就不能换吗?其实也可以换的。因此对主管来说,他们可以按照完全相同的一套标准工序来指导施工班子去建房子。当然他们也可以有自己的独特想法,加入特有工序。

        以上仅个人理解,欢迎交流。如果有描述不当之处,欢迎指正。

  • 相关阅读:
    官场22条潜规则,职场谁说不是呢
    pomelo使用中的常见问题
    马斯诺需求金字塔
    Mac上使用brew安装nvm来支持多版本的Nodejs
    Redis 集群解决方案 Codis
    Linux下压缩某个文件夹(文件夹打包)
    使用forever运行nodejs应用
    nodejs npm常用命令
    Mac安装Brew
    C#2.0 迭代器
  • 原文地址:https://www.cnblogs.com/tongy0/p/5510088.html
Copyright © 2011-2022 走看看