• 【创建型】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就不能换吗?其实也可以换的。因此对主管来说,他们可以按照完全相同的一套标准工序来指导施工班子去建房子。当然他们也可以有自己的独特想法,加入特有工序。

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

  • 相关阅读:
    Codevs 2296 仪仗队 2008年省队选拔赛山东
    Codevs 1535 封锁阳光大学
    Codevs 1069 关押罪犯 2010年NOIP全国联赛提高组
    Codevs 1218 疫情控制 2012年NOIP全国联赛提高组
    Codevs 1684 垃圾陷阱
    洛谷 P1108 低价购买
    Vijos P1325桐桐的糖果计划
    Codevs 3289 花匠 2013年NOIP全国联赛提高组
    Codevs 2611 观光旅游(floyed最小环)
    C语言基础之彩色版C语言(内含linux)
  • 原文地址:https://www.cnblogs.com/tongy0/p/5510088.html
Copyright © 2020-2023  润新知