【2013.1.27】诸葛先生,你到底亮不亮?——Decorator
来源:互联网 发布:努比亚z11mini网络 编辑:程序博客网 时间:2024/05/02 04:31
// // // // // // // // //
///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等。
代码实例:
【大致思路】
BaseComponent作为最基础的接口,实现了此接口的ConcreteComponent用于实现具体功能。同样继承了BaseComponent的Decorator内部封装一个BaseComponent类型的的指针,并在构造器中进行实例实例化。
Decorator.h
#ifndef _DECORATOR_H_#define _DECORATOR_H_class BaseComponent{public:BaseComponent(){}~BaseComponent(){}virtual void Execute() = 0;};class ConcreteComponent:public BaseComponent{public:ConcreteComponent(){}~ConcreteComponent(){}void Execute();};class Decorator: public BaseComponent{public:Decorator(BaseComponent* com);~Decorator(){}virtual void Execute(){}protected:BaseComponent* component;};class ConcreteDecorator: public Decorator{public:ConcreteDecorator(BaseComponent* com);~ConcreteDecorator(){}void Execute();};#endif
Decorator.cpp
#include "Decorator.h"#include<iostream>void ConcreteComponent::Execute(){std::cout<<"Execute base function."<<std::endl;}Decorator::Decorator(BaseComponent* com):component(com){}ConcreteDecorator::ConcreteDecorator(BaseComponent* com):Decorator(com){}void ConcreteDecorator::Execute(){//Execute base function.component->Execute();//Add extra function.std::cout<<"Add Extra function."<<std::endl;}
main.cpp
#include"Decorator.h"int main(){BaseComponent* baseComponent = new ConcreteComponent();Decorator* newComponent = new ConcreteDecorator(baseComponent);newComponent->Execute();return 0;}
输出结果:
【注意事项】
或许会有人疑惑ConcreteDecorator是干什么用的,
——完全可以在Decorator中实现所有的附加功能。
但这里要声明一点的是,
Decorator类一定不能用来实现具体的功能(小规模除外),
真正的实现过程要在ConcreteDecorator中进行。
这次的代码示例中的"装饰功能"只是多输出一行文字。
但是如果有更多的状态,更多的功能,
再把这些都集成到Decorator中,
那Decorator将变得拥挤不堪,
——自然也将失去Decorator模式的本意。
另外,
ConcreteComponent也是同样的道理,
就像是Widget类的子类Button,TextField,Image一样,
内部集成不同的基础功能。
- 【2013.1.27】诸葛先生,你到底亮不亮?——Decorator
- APP运营需5个阶段,让你把产品做大做强——诸葛
- 【VB.NET——你到底是?】
- 诸葛
- 诸葛——如何摆脱APP速死症?
- 诸葛——怎么做好互联网产品运营?
- 深夜切题——诸葛给我牌
- 爬诸葛找房数据——casting3T
- 诸葛告诉你如何进行数据分析
- 软件设计模式——装饰(Decorator)模式你真的懂吗?
- 浅谈MVC架构—你到底有什么本事
- 浅谈MVC架构—你到底有什么本事
- 浅谈MVC架构—你到底有什么本事
- 浅谈MVC架构—你到底有什么本事!!!
- 浅谈MVC架构—你到底有什么本事
- 装饰模式——Decorator
- design pattern——decorator
- 设计模式—Decorator Pattern
- 代理模式(Proxy)
- shell中source命令和.点命令对当前父shell的影响
- vb写的考试大题答案14,15,16,17,18
- 两个线程同时调用同一个处理函数的互斥问题
- Linux里设置环境变量的三种方法
- 【2013.1.27】诸葛先生,你到底亮不亮?——Decorator
- const
- 利用JDK7的NIO2.0进行I/O读写和文件操作监控
- POCO之Number Format
- Android 绘制动态的曲线图
- 写一个内存拷贝函数
- web.py 环境的配置以及一些basic knowledge
- #,##讲解
- POI 设置Excel样式