【2013.1.27】设计模式C++ 实现——Decorator
// // // // // // // // //
///2013.1.27
// // // // // // // // //
还记得前些天流行这样一个网络文化:
给名人找亲戚。
比如说诸葛亮先生,
不完全统计,
其有以下几个兄弟:
诸葛暗,诸葛闪光,诸葛亮不亮……
诸葛先生的兄弟们同样也神通广大,
每一个都喜欢自比管仲、乐毅,
每一个都能未出茅庐而心中已三分天下,
每一个都能在兵临城下之际而于空城之上淡然弹琴,
每一个都能在冬天岿然不动地扇扇子,
……
除此之外,
每一个都拥有自己的特色:
例如诸葛暗先生在晚上出去可以冒充包大人。。。等
那么,
我们该如何实现这些兄弟呢?
很容易的想到让拥有基础本领的诸葛亮作为基类,
每一个兄弟都去继承他,
再分别添加上自己的独家本领。
如果只有几个的话,
这个方法是没有问题的。
但是如果发动网友寻找诸葛家族百年史的话,
找出来几百万个诸葛XXX,
也都要继承么?
诸葛亮要告诉每个兄弟自己的本领,
然后告诉他们你们也有这些本领(基类功能)。
不管诸葛亮会不会累死,
但等到每个人都知道的时候(程序编译完成,准备执行),
估计上帝都看不到了。
这个时候,
躲在角落里的Decorator模式笑了。
该它出场了。
【核心】Decorator通过继承并聚合基类,并在构造器中将其实例化,从而在不改变原有功能的基础之上实现功能的扩展。
UML图:
Component是基类(诸葛亮先生),
ConcreteComponent是其功能的实现(传入Decorator的构造器中)。
至于ConcreteDecoratorA与ConcreteDecoratorB则是对Decorator实现不同功能的扩展了(就像诸葛暗与诸葛闪光之间的关系)。
在一开始我对Decorator有这样一个困惑,
就是为什么不直接将Component基类组合在Decorator之中,
还要再加一个继承关系呢?
不是能够到达同样的效果的么?
后来我仔细想了一下,
忽然发现自己犯了一个很没智商的问题:
如果只用组合的话,
还是设计模式么?
除此之外,
在网上找到了一个更为确切的答案,能够解决这一困惑:
Decorator是能够忠实地调用原有接口的基础上,进行功能的扩展。
脱离了继承关系,
谁知道你这个装饰器中还有原来方法的调用?(除此之外还有Protected类型不能访问的因素)
其实Decorator模式也是与Proxy,Composite等模式有相像之处的。
具体的区别会在日后涉及到此等模式时再详述。
设计模式之间很多都是共同的,
但是告诉大家一个记忆的方法,
就是名称记忆。
每一个模式的结构,
必然是围绕着其名称而实现的。
比如说Decorator名字就是装饰器,
因此它的功能就是装饰。
装饰是什么?
是添加扩展,在不改变原有结构的基础上,
方便地实现各种功能(取决于传入的Component实例)的扩展。
这个设计模式被广泛的应用于各种平台的Widget(控件)设计之中。
比如说InputWidget,其子类有Number_InputWidget,Char_InputWidget等(泛指)。
Button,其子类有ImageButton,AnimationButton等。