设计模式之装饰模式20170726

结构型设计模式之装饰模式:

一、含义

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。

通俗来讲,装饰模式是对类的功能进行加强或减弱。

二、代码说明

1.主要有两个角色

1)构件

最核心、最原始、最基本的对象,也就是要装饰的对象。

2)装饰角色

把最核心、最原始、最基本的东西装饰成其他东西

2.在用C实现过程中也是参考这种思想,以修饰成绩单举例,具体实现如下:

1)装饰模式使用场景:

 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     DecoratorPatternUsage.c
 5 * Description        :     装饰模式的使用
 6 
 7 book@book-desktop:/work/projects/test/DesignPatterns/DecoratorPattern$ gcc -o DecoratorPatternUsage HighScoreDecorator.c SortDecorator.c DecoratorPattern.c DecoratorPatternUsage.c
 8 book@book-desktop:/work/projects/test/DesignPatterns/DecoratorPattern$ ./DecoratorPatternUsage 
 9 这次语文考试最高是75,数学是78,自然是80
10 尊敬的XXX家长:
11 .......................................
12 语文62,数学65,体育98,自然63
13 .......................................
14                                  家长签名                       
15 家长签名为:老三
16 尊敬的XXX家长:
17 .......................................
18 语文62,数学65,体育98,自然63
19 .......................................
20                                  家长签名                       
21 排名第33
22 家长签名为:老三
23 
24 * Created            :     2017.07.25.
25 * Author            :     Yu Weifeng
26 * Function List         :     
27 * Last Modified     :     
28 * History            :     
29 ******************************************************************************/
30 #include"stdio.h"
31 #include"malloc.h"
32 #include"stdlib.h"
33 #include"string.h"
34 #include"DecoratorPattern.h"
35 
36 
37 
38 
39 /*****************************************************************************
40 -Fuction        : main
41 -Description    : 
42 -Input            : 
43 -Output         : 
44 -Return         : 
45 * Modify Date      Version         Author           Modification
46 * -----------------------------------------------
47 * 2017/07/25    V1.0.0         Yu Weifeng       Created
48 ******************************************************************************/
49 int main(int argc,char **argv)
50 {
51     T_SchoolReport tSchoolReport=newFourthGradeSchoolReport;
52 
53     T_Decorator tDecorator=newHighScoreDecorator(tSchoolReport);
54     tDecorator.tDecoratorReport.Report(&tDecorator);
55     tDecorator.tDecoratorReport.Sign(&tDecorator,"老三");
56     //由于向上转型比较难实现,暂不支持多重修饰
57     tDecorator=(T_Decorator)newSortDecorator(tSchoolReport);
58     tDecorator.tDecoratorReport.Report(&tDecorator);
59     tDecorator.tDecoratorReport.Sign(&tDecorator,"老三");
60     return 0;
61 }
DecoratorPatternUsage.c

2)被调用者:

 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     DecoratorPattern.c
 5 * Description        :     装饰模式
 6                         本文件是成绩单的具体实现(未被修饰)
 7                         以修饰成绩单举例    
 8                         
 9 * Created            :     2017.07.25.
10 * Author            :     Yu Weifeng
11 * Function List         :     
12 * Last Modified     :     
13 * History            :     
14 ******************************************************************************/
15 #include"stdio.h"
16 #include"malloc.h"
17 #include"stdlib.h"
18 #include"string.h"
19 #include"DecoratorPattern.h"
20 
21 
22 /*****************************************************************************
23 -Fuction        : SchoolReportReport
24 -Description    : 公有函数
25 -Input            : 
26 -Output         : 
27 -Return         : 
28 * Modify Date      Version         Author           Modification
29 * -----------------------------------------------
30 * 2017/07/25      V1.0.0         Yu Weifeng       Created
31 ******************************************************************************/
32 void SchoolReportReport(void *i_ptThis)
33 {
34     printf("尊敬的XXX家长:
");
35     printf(".......................................
");
36     printf("语文62,数学65,体育98,自然63
");
37     printf(".......................................
");
38     printf("                                 家长签名                       
");
39 }
40 
41 /*****************************************************************************
42 -Fuction        : SchoolReportSign
43 -Description    : 公有函数
44 -Input            : 
45 -Output         : 
46 -Return         : 
47 * Modify Date      Version         Author           Modification
48 * -----------------------------------------------
49 * 2017/07/25      V1.0.0         Yu Weifeng       Created
50 ******************************************************************************/
51 void SchoolReportSign(void *i_ptThis,char *i_strName)
52 {    
53     printf("家长签名为:%s
",i_strName);
54 }
DecoratorPattern.c
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     DecoratorPattern.h
 5 * Description        :     装饰模式
 6                                     
 7 * Created            :     2017.07.25.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #ifndef DECORATOR_PATTERN_H
14 #define DECORATOR_PATTERN_H
15 
16 struct Decorator;
17 
18 typedef struct SchoolReport
19 {
20     void (*Report)(void *i_ptThis);//为保持统一,加入i_ptThis,内部可不使用,
21     void (*Sign)(void *i_ptThis,char *i_strName);//如果使用单例,可以去掉i_ptThis
22 }T_SchoolReport;//由于i_ptThis是T_Decorator 使用,内部使用是要转换为T_Decorator *,也可以把上诉的void *改为struct Decorator*
23 
24 typedef struct Decorator
25 {
26     T_SchoolReport tSchoolReport;//私有变量,不能直接访问
27     T_SchoolReport tDecoratorReport;//修饰,加强功能
28 
29 }T_Decorator;
30 
31 
32 void SchoolReportReport(void *i_ptThis);
33 void SchoolReportSign(void *i_ptThis,char *i_strName);
34 #define newFourthGradeSchoolReport {SchoolReportReport,SchoolReportSign}
35 
36 
37 void HighScoreDecoratorReport(void *i_ptThis);
38 void HighScoreDecoratorSign(void *i_ptThis,char *i_strName);
39 #define newHighScoreDecorator(SchoolReport) {SchoolReport,HighScoreDecoratorReport,HighScoreDecoratorSign}
40 
41 void SortDecoratorReport(void *i_ptThis);
42 void SortDecoratorSign(void *i_ptThis,char *i_strName);
43 #define newSortDecorator(SchoolReport) {SchoolReport,SortDecoratorReport,SortDecoratorSign}
44 
45 #endif
DecoratorPattern.h
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     HighScoreDecorator.c
 5 * Description        :     装饰模式
 6                         本文件是高分修饰类的具体实现
 7                         
 8 * Created            :     2017.07.25.
 9 * Author            :     Yu Weifeng
10 * Function List         :     
11 * Last Modified     :     
12 * History            :     
13 ******************************************************************************/
14 #include"stdio.h"
15 #include"malloc.h"
16 #include"stdlib.h"
17 #include"string.h"
18 #include"DecoratorPattern.h"
19 
20 
21 
22 /*****************************************************************************
23 -Fuction        : ReportHighScore
24 -Description    : 公有函数
25 -Input            : 
26 -Output         : 
27 -Return         : 
28 * Modify Date      Version         Author           Modification
29 * -----------------------------------------------
30 * 2017/07/25      V1.0.0         Yu Weifeng       Created
31 ******************************************************************************/
32 static void ReportHighScore()
33 {
34     printf("这次语文考试最高是75,数学是78,自然是80
");
35 }
36 
37 /*****************************************************************************
38 -Fuction        : HighScoreDecoratorReport
39 -Description    : 公有函数
40 -Input            : 
41 -Output         : 
42 -Return         : 
43 * Modify Date      Version         Author           Modification
44 * -----------------------------------------------
45 * 2017/07/25      V1.0.0         Yu Weifeng       Created
46 ******************************************************************************/
47 void HighScoreDecoratorReport(void *i_ptThis)
48 {
49     T_Decorator *ptHighScoreDecorator=(T_Decorator *)i_ptThis;
50     ReportHighScore();
51     ptHighScoreDecorator->tSchoolReport.Report((void *)ptHighScoreDecorator);
52 }
53 
54 /*****************************************************************************
55 -Fuction        : DecoratorSign
56 -Description    : 公有函数
57 -Input            : 
58 -Output         : 
59 -Return         : 
60 * Modify Date      Version         Author           Modification
61 * -----------------------------------------------
62 * 2017/07/25      V1.0.0         Yu Weifeng       Created
63 ******************************************************************************/
64 void HighScoreDecoratorSign(void *i_ptThis,char *i_strName)
65 {    
66     T_Decorator *ptHighScoreDecorator=(T_Decorator *)i_ptThis;
67     ptHighScoreDecorator->tSchoolReport.Sign((void *)ptHighScoreDecorator,i_strName);
68 }
HighScoreDecorator.c
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     SortDecorator.c
 5 * Description        :     装饰模式
 6                         本文件是排名类的具体实现
 7                         
 8 * Created            :     2017.07.25.
 9 * Author            :     Yu Weifeng
10 * Function List         :     
11 * Last Modified     :     
12 * History            :     
13 ******************************************************************************/
14 #include"stdio.h"
15 #include"malloc.h"
16 #include"stdlib.h"
17 #include"string.h"
18 #include"DecoratorPattern.h"
19 
20 
21 
22 /*****************************************************************************
23 -Fuction        : ReportHighScore
24 -Description    : 公有函数
25 -Input            : 
26 -Output         : 
27 -Return         : 
28 * Modify Date      Version         Author           Modification
29 * -----------------------------------------------
30 * 2017/07/25      V1.0.0         Yu Weifeng       Created
31 ******************************************************************************/
32 static void ReportSort()
33 {
34     printf("排名第33
");
35 }
36 /*****************************************************************************
37 -Fuction        : SortDecoratorReport
38 -Description    : 公有函数
39 -Input            : 
40 -Output         : 
41 -Return         : 
42 * Modify Date      Version         Author           Modification
43 * -----------------------------------------------
44 * 2017/07/25      V1.0.0         Yu Weifeng       Created
45 ******************************************************************************/
46 void SortDecoratorReport(void *i_ptThis)
47 {
48     T_Decorator *ptSortDecorator=(T_Decorator *)i_ptThis;
49     ptSortDecorator->tSchoolReport.Report((void *)ptSortDecorator);
50     ReportSort();
51 }
52 
53 /*****************************************************************************
54 -Fuction        : SortDecoratorSign
55 -Description    : 公有函数
56 -Input            : 
57 -Output         : 
58 -Return         : 
59 * Modify Date      Version         Author           Modification
60 * -----------------------------------------------
61 * 2017/07/25      V1.0.0         Yu Weifeng       Created
62 ******************************************************************************/
63 void SortDecoratorSign(void *i_ptThis,char *i_strName)
64 {    
65     T_Decorator *ptSortDecorator=(T_Decorator *)i_ptThis;
66     ptSortDecorator->tSchoolReport.Sign((void *)ptSortDecorator,i_strName);
67 }
SortDecorator.c

3)执行结果:

book@book-desktop:/work/projects/test/DesignPatterns/DecoratorPattern$ gcc -o DecoratorPatternUsage HighScoreDecorator.c SortDecorator.c DecoratorPattern.c DecoratorPatternUsage.c

book@book-desktop:/work/projects/test/DesignPatterns/DecoratorPattern$ ./DecoratorPatternUsage

这次语文考试最高是75,数学是78,自然是80

尊敬的XXX家长:

.......................................

语文62,数学65,体育98,自然63

.......................................

                                 家长签名                      

家长签名为:老三

尊敬的XXX家长:

.......................................

语文62,数学65,体育98,自然63

.......................................

                                 家长签名                      

排名第33

家长签名为:老三

4)详细代码:

https://github.com/fengweiyu/DesignThinking/tree/master/DesignPatterns/StructuralDesignPatterns/DecoratorPattern

三、使用场景

1.需要扩展一个类的功能,或给一个类增加附加功能

2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销

3.需要为一批的兄弟类进行改装或加装功能,当然是首选装饰模式

四、优点

1.装饰类和被装饰类可以独立发展,而不会相互耦合。

2.装饰模式是继承关系的一个替代方案(如果继承超过两层就要考虑不再使用继承)

3.装饰模式可以动态地扩展一个实现类的功能(不用则不修饰(即场景中不使用即可),实现动态扩展),而继承就必须修改程序。

4.扩展性非常好

在继承关系中增强上层角色功能,又不影响其子类,可以通过装饰模式重新封装一个类,相当于创建了一个新的类,而不是通过继承来完成,这样对原有程序没有变更,风险最小。

(桥梁模式也可以代替继承来避免风险,使用场景不一样(装饰模式着重增强功能),但有点类似)

五、缺点

多层的装饰是比较复杂的,如果是最里层的装饰出现问题,那排查解决的工作量会很大,因此,尽量减少装饰类的数量,以便降低系统的复杂度。

六、与其他模式的区别

1、装饰模式与代理模式

装饰模式就是代理模式的一个特殊应用,两者的共同点是都具有相同的接口,

不同点则是代理模式着重对代理过程的控制,它不对被代理类的功能做任何处理,保证原滋原味的调用。

而装饰模式则是对类的功能进行加强或减弱,它着重类的功能变化,它不做准入条件判断和准入参数过滤。

2、装饰模式与适配器模式

相似的地方:

都是包装作用,都是通过委托方式实现其功能。

不同点是:

装饰模式包装的是自己的兄弟类,隶属于同一个家族(相同接口或父类),

适配器模式则修改非血缘关系类,把一个非本家族的对象伪装成本家族的对象,注意是伪装,因此它的本质还是非相同接口的对象。

具体来说:

1)意图不同

装饰模式的意图是加强对象的功能,

适配器模式关注的则是转化,它的主要意图是两个不同对象之间的转化

2)施与对象不同

装饰模式装饰的对象必须是自己的同宗,也就是相同的接口或父类,只要在具有相同的属性和行为的情况下,才能比较行为是增强还是减弱;

适配器模式则必须是两个不同的对象,因为它着重与转换,只有两个不同的对象才有转换的必要。

3)场景不同

装饰模式在任何时候都可以使用,只要是想增强类的功能,

而适配器模式则是一个补救模式,一般出现在系统成熟或已经构建完毕的项目中,作为一个紧急处理手段采用。

4)扩展性不同

装饰模式很容易扩展,

但是适配器模式就不同了,它在两个不同对象之间架起了一座沟通的桥梁,建立容易,去掉就比较困难了,需要从系统整体考虑是否能够撤销。

3、装饰模式与其他包装模式的区别:

自己不处理让其他人处理,这种类型的模式定义一个名字,叫做包装模式。包装模式包括:装饰模式、适配器模式、门面模式、代理模式、桥梁模式。

5个包装模式都是通过委托的方式对一个对象或一系列对象施行包装,有了包装,设计的系统才更加灵活、稳定,并且极具扩展性。从实现的角度来看,它们都是代理的一种具体表现形式,它们在使用场景上的区别如下:

1)代理模式主要用在不希望展示一个对象内部细节的场景中,此外,代理模式还可以用在一个对象的访问需要限制的场景中。

2)装饰模式是一种特殊的代理模式,它倡导的是在不改变接口的前提下为对象增强功能,或者动态添加额外职责。就扩展性而言,它比子类更灵活。

3)适配器模式的主要意图是接口转换,把一个对象的接口转换成系统希望的另外一个接口。这里的系统指的不仅仅是一个应用,也可能是某个环境,比如通过接口转换可以屏蔽外界接口,以免外界接口深入系统内部,从而提高系统的稳定性和可靠性

4)桥梁模式是在抽象层产生耦合,解决的是自行扩展的问题,它可以使两个有耦合关系的对象互不影响地扩展。

5)门面模式是一个粗粒度的封装,它提供一个方便访问子系统的接口,不具有任何的业务逻辑,仅仅是一个访问复杂系统的快速通道,没有它,子系统照样运行。

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