zoukankan      html  css  js  c++  java
  • 设计模式之建造者模式20170802

    创建型设计模式之建造者模式:

    一、含义

    建造者模式也叫做生成器模式,其定义如下:

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

    通俗地说,

    建造者通过零件的组装来建造对象,组装顺序不同对象效能也不同(产生不同的对象)

    二、代码说明

    1.主要有三个角色

    1)产品类角色

    通常实现了模版方法模式,也就是有模版方法和基本方法

    2)建造者角色

    规范产品的组建,并且返回一个组建好的对象

    3)导演类角色

    负责安排已有模块的顺序,然后告诉建造者开始建造。

    导演类起到封装的作用,避免高层模块深入到建造者内部的实现类。当然,在建造者模式比较庞大时,导演类可以有多个。

    2.在用C实现过程中也是参考这种思想,以创造各种超人举例,具体实现如下:

    1)建造者模式使用场景:

     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     BuilderPatternUsage.c
     5 * Description        :     建造者模式的使用
     6 
     7 book@book-desktop:/work/projects/test/DesignPatterns/BuilderPattern$ gcc -o BuilderPatternUsage SuperMan.c AdultSuperManBuilder.c Builder.c ChildSuperManBuilder.c BuilderPattern.c BuilderPatternUsage.c 
     8 book@book-desktop:/work/projects/test/DesignPatterns/BuilderPattern$ ./BuilderPatternUsage 
     9 ------------创造成年超人:------------
    10 成年超人的天赋是:刀枪不入
    11 -----------创造未成年超人:-----------
    12 未成年超人的天赋是:会飞行
    13 
    14 * Created            :     2017.08.01.
    15 * Author            :     Yu Weifeng
    16 * Function List         :     
    17 * Last Modified     :     
    18 * History            :     
    19 ******************************************************************************/
    20 #include <stdio.h>
    21 #include <stdlib.h>
    22 #include <string.h>
    23 #include "BuilderPattern.h"
    24 
    25 
    26 
    27 
    28 /*****************************************************************************
    29 -Fuction        : main
    30 -Description    : 
    31 -Input            : 
    32 -Output         : 
    33 -Return         : 
    34 * Modify Date      Version         Author           Modification
    35 * -----------------------------------------------
    36 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    37 ******************************************************************************/
    38 int main(int argc,char **argv)
    39 {
    40     printf("------------创造成年超人:------------
    ");
    41     T_SuperMan tAdultSuperMan=g_tDirector.GetAdultSuperMan();
    42     printf("成年超人的天赋是:%s
    ",tAdultSuperMan.GetSpecialTalent(&tAdultSuperMan));
    43     
    44     printf("-----------创造未成年超人:-----------
    ");
    45     T_SuperMan tChildSuperMan=g_tDirector.GetChildSuperMan();
    46     printf("未成年超人的天赋是:%s
    ",tChildSuperMan.GetSpecialTalent(&tChildSuperMan));
    47     
    48     return 0;
    49 }
    BuilderPatternUsage.c

    2)被调用者:

     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     BuilderPattern.c
     5 * Description        :     建造者模式
     6                         本文件是导演类的具体实现
     7                         以创造各种超人举例    
     8                         
     9 * Created            :     2017.08.01.
    10 * Author            :     Yu Weifeng
    11 * Function List         :     
    12 * Last Modified     :     
    13 * History            :     
    14 ******************************************************************************/
    15 #include <stdio.h>
    16 #include <stdlib.h>
    17 #include <string.h>
    18 #include "BuilderPattern.h"
    19 
    20 void SuperManSetBody(T_SuperMan *ptThis,char *i_strBody);
    21 char * SuperManGetBody(T_SuperMan *ptThis);
    22 void SuperManSetSpecialTalent(T_SuperMan *ptThis,char *i_strSpecialTalent);
    23 char * SuperManGetSpecialTalent(T_SuperMan *ptThis);
    24 void SuperManSetSpecialSymbol(T_SuperMan *ptThis,char *i_strSpecialSymbol);
    25 char * SuperManGetSpecialSymbol(T_SuperMan *ptThis);
    26 #define newSuperMan {NULL,NULL,NULL,SuperManSetBody,SuperManGetBody,SuperManSetSpecialTalent,
    27                     SuperManGetSpecialTalent,SuperManSetSpecialSymbol,SuperManGetSpecialSymbol}
    28 
    29 void BuilderSetBody(T_Builder *ptThis,char *i_strBody);
    30 void BuilderSetSpecialTalent(T_Builder *ptThis,char *i_strSpecialTalent);
    31 void BuilderSetSpecialSymbol(T_Builder *ptThis,char *i_strSpecialSymbol);
    32 
    33 T_SuperMan AdultBuilderGetSuperMan(T_Builder *ptThis);
    34 #define newAdultBuilder {newSuperMan,BuilderSetBody,BuilderSetSpecialTalent,BuilderSetSpecialSymbol,AdultBuilderGetSuperMan}
    35 
    36 T_SuperMan ChildBuilderGetSuperMan(T_Builder *ptThis);
    37 #define newChildBuilder {newSuperMan,BuilderSetBody,BuilderSetSpecialTalent,BuilderSetSpecialSymbol,ChildBuilderGetSuperMan}
    38 
    39 
    40 static T_Builder g_tAdultBuilder=newAdultBuilder;
    41 static T_Builder g_tChildBuilder=newChildBuilder;
    42 static T_SuperMan GetAdultSuperMan();
    43 static T_SuperMan GetChildSuperMan();
    44 const T_Director g_tDirector={
    45     .GetAdultSuperMan=GetAdultSuperMan,
    46     .GetChildSuperMan=GetChildSuperMan,
    47 };
    48 
    49 
    50 
    51 /*****************************************************************************
    52 -Fuction        : GetAdultSuperMan
    53 -Description    : 
    54 -Input            : 
    55 -Output         : 
    56 -Return         : 
    57 * Modify Date      Version         Author           Modification
    58 * -----------------------------------------------
    59 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    60 ******************************************************************************/
    61 static T_SuperMan GetAdultSuperMan()
    62 {
    63     return g_tAdultBuilder.GetSuperMan(&g_tAdultBuilder);
    64 }
    65 
    66 /*****************************************************************************
    67 -Fuction        : GetChildSuperMan
    68 -Description    : 
    69 -Input            : 
    70 -Output         : 
    71 -Return         : 
    72 * Modify Date      Version         Author           Modification
    73 * -----------------------------------------------
    74 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    75 ******************************************************************************/
    76 static T_SuperMan GetChildSuperMan()
    77 {
    78     return g_tChildBuilder.GetSuperMan(&g_tChildBuilder);
    79 }
    BuilderPattern.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     BuilderPattern.h
     5 * Description        :     建造者模式
     6                                     
     7 * Created            :     2017.08.01.
     8 * Author            :     Yu Weifeng
     9 * Function List         :     
    10 * Last Modified     :     
    11 * History            :     
    12 ******************************************************************************/
    13 #ifndef BUILDER_PATTERN_H
    14 #define BUILDER_PATTERN_H
    15 
    16 typedef struct SuperMan
    17 {
    18     char *strBody;//私有变量,禁止直接访问
    19     char *strSpecialTalent;//私有变量,禁止直接访问
    20     char *strSpecialSymbol;//私有变量,禁止直接访问
    21     void (*SetBody)(struct SuperMan *ptThis,char *i_strBody);
    22     char * (*GetBody)(struct SuperMan *ptThis);
    23     void (*SetSpecialTalent)(struct SuperMan *ptThis,char *i_strSpecialTalent);
    24     char * (*GetSpecialTalent)(struct SuperMan *ptThis);
    25     void (*SetSpecialSymbol)(struct SuperMan *ptThis,char *i_strSpecialSymbol);    
    26     char * (*GetSpecialSymbol)(struct SuperMan *ptThis);
    27 }T_SuperMan;
    28 
    29 typedef struct Builder
    30 {
    31     T_SuperMan tSuperMan;
    32     void (*SetBody)(struct Builder *ptThis,char *i_strBody);
    33     void (*SetSpecialTalent)(struct Builder *ptThis,char *i_strSpecialTalent);
    34     void (*SetSpecialSymbol)(struct Builder *ptThis,char *i_strSpecialSymbol);
    35     T_SuperMan (*GetSuperMan)(struct Builder *ptThis);
    36 }T_Builder;
    37 
    38 typedef struct Director
    39 {
    40     T_SuperMan (*GetAdultSuperMan)();
    41     T_SuperMan (*GetChildSuperMan)();
    42 }T_Director;
    43 
    44 const T_Director g_tDirector;
    45 
    46 
    47 #endif
    BuilderPattern.h
      1 /*****************************************************************************
      2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
      3 ------------------------------------------------------------------------------
      4 * File Module        :     SuperMan.c
      5 * Description        :     建造者模式
      6                         本文件是超人的具体实现
      7                         
      8 * Created            :     2017.08.01.
      9 * Author            :     Yu Weifeng
     10 * Function List         :     
     11 * Last Modified     :     
     12 * History            :     
     13 ******************************************************************************/
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <string.h>
     17 #include "BuilderPattern.h"
     18 
     19 
     20 
     21 /*****************************************************************************
     22 -Fuction        : SuperManSetBody
     23 -Description    : 公有函数
     24 -Input            : 
     25 -Output         : 
     26 -Return         : 
     27 * Modify Date      Version         Author           Modification
     28 * -----------------------------------------------
     29 * 2017/08/01    V1.0.0         Yu Weifeng       Created
     30 ******************************************************************************/
     31 void SuperManSetBody(T_SuperMan *ptThis,char *i_strBody)
     32 {
     33     ptThis->strBody=i_strBody;
     34 }
     35 
     36 /*****************************************************************************
     37 -Fuction        : SuperManGetBody
     38 -Description    : 公有函数
     39 -Input            : 
     40 -Output         : 
     41 -Return         : 
     42 * Modify Date      Version         Author           Modification
     43 * -----------------------------------------------
     44 * 2017/08/01    V1.0.0         Yu Weifeng       Created
     45 ******************************************************************************/
     46 char * SuperManGetBody(T_SuperMan *ptThis)
     47 {
     48     return ptThis->strBody;
     49 }
     50 /*****************************************************************************
     51 -Fuction        : SuperManSetBody
     52 -Description    : 公有函数
     53 -Input            : 
     54 -Output         : 
     55 -Return         : 
     56 * Modify Date      Version         Author           Modification
     57 * -----------------------------------------------
     58 * 2017/08/01    V1.0.0         Yu Weifeng       Created
     59 ******************************************************************************/
     60 void SuperManSetSpecialTalent(T_SuperMan *ptThis,char *i_strSpecialTalent)
     61 {
     62     ptThis->strSpecialTalent=i_strSpecialTalent;
     63 }
     64 
     65 /*****************************************************************************
     66 -Fuction        : SuperManGetBody
     67 -Description    : 公有函数
     68 -Input            : 
     69 -Output         : 
     70 -Return         : 
     71 * Modify Date      Version         Author           Modification
     72 * -----------------------------------------------
     73 * 2017/08/01    V1.0.0         Yu Weifeng       Created
     74 ******************************************************************************/
     75 char * SuperManGetSpecialTalent(T_SuperMan *ptThis)
     76 {
     77     return ptThis->strSpecialTalent;
     78 }
     79 /*****************************************************************************
     80 -Fuction        : SuperManSetBody
     81 -Description    : 公有函数
     82 -Input            : 
     83 -Output         : 
     84 -Return         : 
     85 * Modify Date      Version         Author           Modification
     86 * -----------------------------------------------
     87 * 2017/08/01    V1.0.0         Yu Weifeng       Created
     88 ******************************************************************************/
     89 void SuperManSetSpecialSymbol(T_SuperMan *ptThis,char *i_strSpecialSymbol)
     90 {
     91     ptThis->strSpecialSymbol=i_strSpecialSymbol;
     92 }
     93 
     94 /*****************************************************************************
     95 -Fuction        : SuperManGetBody
     96 -Description    : 公有函数
     97 -Input            : 
     98 -Output         : 
     99 -Return         : 
    100 * Modify Date      Version         Author           Modification
    101 * -----------------------------------------------
    102 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    103 ******************************************************************************/
    104 char * SuperManGetSpecialSymbol(T_SuperMan *ptThis)
    105 {
    106     return ptThis->strSpecialSymbol;
    107 }
    SuperMan.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     Builder.c
     5 * Description        :     建造者模式
     6                         本文件是建造者的具体实现
     7                         
     8 * Created            :     2017.08.01.
     9 * Author            :     Yu Weifeng
    10 * Function List         :     
    11 * Last Modified     :     
    12 * History            :     
    13 ******************************************************************************/
    14 #include <stdio.h>
    15 #include <stdlib.h>
    16 #include <string.h>
    17 #include "BuilderPattern.h"
    18 
    19 
    20 
    21 /*****************************************************************************
    22 -Fuction        : BuilderSetBody
    23 -Description    : 公有函数
    24 -Input            : 
    25 -Output         : 
    26 -Return         : 
    27 * Modify Date      Version         Author           Modification
    28 * -----------------------------------------------
    29 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    30 ******************************************************************************/
    31 void BuilderSetBody(T_Builder *ptThis,char *i_strBody)
    32 {
    33     ptThis->tSuperMan.SetBody(&ptThis->tSuperMan,i_strBody);
    34 }
    35 
    36 /*****************************************************************************
    37 -Fuction        : BuilderSetSpecialTalent
    38 -Description    : 公有函数
    39 -Input            : 
    40 -Output         : 
    41 -Return         : 
    42 * Modify Date      Version         Author           Modification
    43 * -----------------------------------------------
    44 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    45 ******************************************************************************/
    46 void BuilderSetSpecialTalent(T_Builder *ptThis,char *i_strSpecialTalent)
    47 {
    48     ptThis->tSuperMan.SetSpecialTalent(&ptThis->tSuperMan,i_strSpecialTalent);
    49 }
    50 
    51 /*****************************************************************************
    52 -Fuction        : BuilderSetSpecialSymbol
    53 -Description    : 公有函数
    54 -Input            : 
    55 -Output         : 
    56 -Return         : 
    57 * Modify Date      Version         Author           Modification
    58 * -----------------------------------------------
    59 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    60 ******************************************************************************/
    61 void BuilderSetSpecialSymbol(T_Builder *ptThis,char *i_strSpecialSymbol)
    62 {
    63     ptThis->tSuperMan.SetSpecialSymbol(&ptThis->tSuperMan,i_strSpecialSymbol);
    64 }
    Builder.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     AdultSuperManBuilder.c
     5 * Description        :     建造者模式
     6                         本文件是成年超人建造者的具体实现
     7                         
     8 * Created            :     2017.08.01.
     9 * Author            :     Yu Weifeng
    10 * Function List         :     
    11 * Last Modified     :     
    12 * History            :     
    13 ******************************************************************************/
    14 #include <stdio.h>
    15 #include <stdlib.h>
    16 #include <string.h>
    17 #include "BuilderPattern.h"
    18 
    19 
    20 
    21 /*****************************************************************************
    22 -Fuction        : AdultBuilderGetSuperMan
    23 -Description    : 公有函数
    24 -Input            : 
    25 -Output         : 
    26 -Return         : 
    27 * Modify Date      Version         Author           Modification
    28 * -----------------------------------------------
    29 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    30 ******************************************************************************/
    31 T_SuperMan AdultBuilderGetSuperMan(T_Builder *ptThis)
    32 {
    33     ptThis->SetBody(ptThis,"强壮的躯体");
    34     ptThis->SetSpecialTalent(ptThis,"刀枪不入");
    35     ptThis->SetSpecialSymbol(ptThis,"胸前带小S标记");
    36     return ptThis->tSuperMan;
    37 }
    AdultSuperManBuilder.c
     1 /*****************************************************************************
     2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
     3 ------------------------------------------------------------------------------
     4 * File Module        :     ChildSuperManBuilder.c
     5 * Description        :     建造者模式
     6                         本文件是未成年超人建造者的具体实现
     7                         
     8 * Created            :     2017.08.01.
     9 * Author            :     Yu Weifeng
    10 * Function List         :     
    11 * Last Modified     :     
    12 * History            :     
    13 ******************************************************************************/
    14 #include <stdio.h>
    15 #include <stdlib.h>
    16 #include <string.h>
    17 #include "BuilderPattern.h"
    18 
    19 
    20 
    21 /*****************************************************************************
    22 -Fuction        : ChildBuilderGetSuperMan
    23 -Description    : 公有函数
    24 -Input            : 
    25 -Output         : 
    26 -Return         : 
    27 * Modify Date      Version         Author           Modification
    28 * -----------------------------------------------
    29 * 2017/08/01    V1.0.0         Yu Weifeng       Created
    30 ******************************************************************************/
    31 T_SuperMan ChildBuilderGetSuperMan(T_Builder *ptThis)
    32 {
    33     ptThis->SetBody(ptThis,"强壮的躯体");
    34     ptThis->SetSpecialTalent(ptThis,"会飞行");
    35     ptThis->SetSpecialSymbol(ptThis,"胸前带S标记");
    36     return ptThis->tSuperMan;
    37 }
    ChildSuperManBuilder.c

    3)执行结果:

    book@book-desktop:/work/projects/test/DesignPatterns/BuilderPattern$ gcc -o BuilderPatternUsage SuperMan.c AdultSuperManBuilder.c Builder.c ChildSuperManBuilder.c BuilderPattern.c BuilderPatternUsage.c

    book@book-desktop:/work/projects/test/DesignPatterns/BuilderPattern$ ./BuilderPatternUsage

    ------------创造成年超人:------------

    成年超人的天赋是:刀枪不入

    -----------创造未成年超人:-----------

    未成年超人的天赋是:会飞行

    4)详细代码:

    https://github.com/fengweiyu/DesignThinking/tree/master/DesignPatterns/CreationalDesignPatterns/BuilderPattern

    三、使用场景

    1.相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。

    2.多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。

    3.产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常适合。

    4.在对象创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。

    这种场景只能是一个补偿方法,因为一个对象不容易获得,在设计阶段竟然没有发觉,本身已经违反设计的最初目标。

    四、优点

    1.封装性

    使用建造者模式可以使客户端不必知道产品内部组成的细节

    2.建造者独立,容易扩展

    建造者相互对立的,对系统的扩展非常有利。

    3.便于控制细节风险

    由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。

    五、建造者模式的扩展

    1.建造者组装零件,组装顺序不同对象效能也不同,(产品类中)引入模版方法模式能更好地达到这种效果,也是一个非常简单而有效的办法。

    六、与其他模式的区别

    1、建造者模式与工厂方法模式

    工厂方法模式注重的是整体对象的创建方法,而建造者模式注重的是部件构建的过程。具体来说,

    1)意图不同

    在工厂方法模式里,我们关注的是一个产品整体;但在建造这模式中,关注的是 由零件一步一步地组装出产品对象。

    简单的说,工厂模式是一个对象创建的粗线条应用,建造者模式则是通过细线条勾勒出一个复杂对象,关注的是产品组成部分的创建过程。

    2)产品的复杂度不同

    工厂方法模式创建的产品一般都是单一性质产品,都是一个模样;而建造者模式创建的则是一个复合产品,它由各个部件复合而成,部件不同产品对象当然不同。这不是说工厂方法模式创建的对象简单,而是指它们的粒度大小不同。一般来说工厂方法模式的对象粒度比较粗,建造者模式的产品对象粒度比较细。

    两种模式的选择,完全取决于在做系统设计时的意图,如果需要详细关注一个产品部件的生产、安装步骤,则选择建造者,否则选择工厂方法模式。

    2、建造者模式与抽象工厂模式

    抽象工厂模式实现对产品家族的创建,一个产品家族是这样的一系列产品:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关系构建过程,只关心什么产品由什么工厂生成即可。

    而建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新产品,两者的区别还是比较明显的。

    具体来说,

    1)抽象工厂模式就好比是一个一个的工厂,对外界来说,只要关心一个工厂到底是生产什么产品的,不用关心具体怎么生产。

    而建造者模式就不同了,它是由车间组成,不同的车间完成不同的创建和装配任务,车间主任(导演类)给建造车间什么蓝图就能生产什么产品,建造者模式更关心建造过程。

    2)相对来说,抽象工厂模式比建造者模式的尺度要大,它关注产品整体,而建造者模式关注构建过程,因此建造者模式可以很容易地构建出一个崭新的产品,只要导演类能够提供具体的工艺流程。

    3)两者的应用场景截然不同,如果希望屏蔽对象的创建过程,只提供一个封装良好的对象,则可以选择抽象工厂方法模式。

    而建造者模式可以用在构件的装配方面,如通过装配不同的组件或相同组件的不同顺序,可以产生出一个新的对象,它可以产生一个非常灵活的架构,方便地扩展和维护系统。

  • 相关阅读:
    js高级-闭包
    js作用域
    js执行上下文与执行上下文栈
    js原型及原型链
    去除数组中重复的元素值
    树[省选联考2020]
    GDOI2020 游记
    Problem b[HAOI2011]
    分零食[JSOI2012]
    移动金币「SDOI2019」
  • 原文地址:https://www.cnblogs.com/yuweifeng/p/7275632.html
Copyright © 2011-2022 走看看