设计模式之建造者模式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)两者的应用场景截然不同,如果希望屏蔽对象的创建过程,只提供一个封装良好的对象,则可以选择抽象工厂方法模式。

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

原文地址:https://www.cnblogs.com/yuweifeng/p/7275632.html