【设计模式系列】结构型模式之Decorator模式
2012-04-11 16:57
302 查看
概要
[align=left]又是一种比较常见也比较常用的模式。系统模块经常需要进行功能上的扩展,比如下面这种形式的结构,[/align]
[align=left]当需要扩展新Function时,通常会通过继承追加新类来实现功能的扩展。但是如果我们不是扩展一个新功能的对象,而只是对所有现有的每种功能类的处理进行扩展时,我们应该怎么做?Decorator模式可以很好的解决这类问题。[/align]
目的
为一系列对象动态追加(或删除)额外的功能,并保证统一的外部接口
实例
考虑这样一个比较典型的例子吧。UI中会用到很多种的window,比如对话框,菜单,tab窗口,树状窗口等。
如果有需求需要追加这样的功能:为每种window控件都追加在window框中显示某个logo的功能,怎么解决?
最笨的方法:每种window都加这种功能,通过isShowlogo变量来决定是否显示logo,
每种window都要改,太麻烦了,我想每个开发者都不会愿意这样去扩展。也许有人会说,上面的方法还可以稍微改善一下,比如说把显示logo的处理都放在基类来进行:
但是首先这样会涉及到对基类和子类调用方式的调整,其次把logo显示的处理跟原来的处理耦合在一起会带来额外的风险,同时如果又需要对这些window再统一添加其他功能时又会涉及到再次的复杂的改动,扩展性比较差。
那么让我们进入正题,还是看看Decorator模式怎么解决的。
从BaseWin类继承添加DecoratorWin类,它包含一个指向BaseWin对象的指针,它的Show方法调用mWin指向的BaseWin对象的Show方法。具体扩展时再从DecoratorWin类继承来实现,比如LogWin类实现了显示Logo的方法,并在Show方法中调用显示Logo方法。当然对接口使用Client端来说是不用关心内部处理的,因为它们都具有统一的外部接口。如下所示是Client端调用带有Logo显示的TabWin的处理。
这样的扩展有什么好处呢?第一,改动范围小,而且不需要调整原有的代码,变更风险小;第二,可扩展性强,模块灵活性强;第三;扩展类具有跟原来一致的外部接口。
[align=left]应用[/align]
Decorator除了可以追加功能外,也可以统一去剥离现有的部分功能。当然由于Decorator模式是在运行时动态的改变对象职责,所以也会给调试增加一定难度。从目前已知应用来看,使用时相当广泛的,比如对一些IOStream的封装和扩展,而在GUI工具库中Decorator模式的使用的是最多的。另外,也要区分清楚Adapter模式和Decorator模式的区别,Adapter模式改变的是对象的接口,而Decorator改变的是对象的功能。
[align=left]又是一种比较常见也比较常用的模式。系统模块经常需要进行功能上的扩展,比如下面这种形式的结构,[/align]
[align=left]当需要扩展新Function时,通常会通过继承追加新类来实现功能的扩展。但是如果我们不是扩展一个新功能的对象,而只是对所有现有的每种功能类的处理进行扩展时,我们应该怎么做?Decorator模式可以很好的解决这类问题。[/align]
目的
为一系列对象动态追加(或删除)额外的功能,并保证统一的外部接口
实例
考虑这样一个比较典型的例子吧。UI中会用到很多种的window,比如对话框,菜单,tab窗口,树状窗口等。
class BaseWin { public: virtual void Show(); }; class TabWin : public BaseWin { public: virtual void Show(); }; class TreeWin : public BaseWin { public: virtual void Show(); }; ......
如果有需求需要追加这样的功能:为每种window控件都追加在window框中显示某个logo的功能,怎么解决?
最笨的方法:每种window都加这种功能,通过isShowlogo变量来决定是否显示logo,
class BaseWin { public: virtual void Show(); virtual void DisplayLogo(); protected: BOOL mIsShowLogo; }; class TabWin : public BaseWin { public: virtual void Show() { if (mIsShowLogo) { DisplayLogo(); } ...... } }; class TreeWin : public BaseWin { public: virtual void Show() { if (mIsShowLogo) { DisplayLogo(); } ...... } }; ......
每种window都要改,太麻烦了,我想每个开发者都不会愿意这样去扩展。也许有人会说,上面的方法还可以稍微改善一下,比如说把显示logo的处理都放在基类来进行:
class BaseWin { public: virtual void Show() { if (mIsShowLogo) { DisplayLogo(); } WinShow(); } virtual void WinShow(); virtual void DisplayLogo(); protected: BOOL mIsShowLogo; }; class TabWin : public BaseWin { public: virtual void WinShow(); }; class TreeWin : public BaseWin { public: virtual void WinShow() ; }; ......
但是首先这样会涉及到对基类和子类调用方式的调整,其次把logo显示的处理跟原来的处理耦合在一起会带来额外的风险,同时如果又需要对这些window再统一添加其他功能时又会涉及到再次的复杂的改动,扩展性比较差。
那么让我们进入正题,还是看看Decorator模式怎么解决的。
class BaseWin { public: virtual void Show(); }; class TabWin : public BaseWin { public: virtual void Show(); }; class TreeWin : public BaseWin { public: virtual void Show(); }; ......
class DecoratorWin: public BaseWin {
public:
DecoratorWin(BaseWin* win) {
mWin = win;
}
virtual void Show() {
mWin->Show();
}
private:
BaseWin* mWin;
};
class LogWin: public DecoratorWin {
public:
LogWin(BaseWin* win) : Decorator(win){
}
void DisplayLogo();
virtual void Show() {
DisplayLogo();
DecoratorWin::Show();
}
};
从BaseWin类继承添加DecoratorWin类,它包含一个指向BaseWin对象的指针,它的Show方法调用mWin指向的BaseWin对象的Show方法。具体扩展时再从DecoratorWin类继承来实现,比如LogWin类实现了显示Logo的方法,并在Show方法中调用显示Logo方法。当然对接口使用Client端来说是不用关心内部处理的,因为它们都具有统一的外部接口。如下所示是Client端调用带有Logo显示的TabWin的处理。
BaseWin* tab = new TabWin(); BaseWin* logo = new LogWin(tab); logo->Show();
这样的扩展有什么好处呢?第一,改动范围小,而且不需要调整原有的代码,变更风险小;第二,可扩展性强,模块灵活性强;第三;扩展类具有跟原来一致的外部接口。
[align=left]应用[/align]
Decorator除了可以追加功能外,也可以统一去剥离现有的部分功能。当然由于Decorator模式是在运行时动态的改变对象职责,所以也会给调试增加一定难度。从目前已知应用来看,使用时相当广泛的,比如对一些IOStream的封装和扩展,而在GUI工具库中Decorator模式的使用的是最多的。另外,也要区分清楚Adapter模式和Decorator模式的区别,Adapter模式改变的是对象的接口,而Decorator改变的是对象的功能。
相关文章推荐
- 设计模式总结篇系列:装饰器模式(Decorator)
- 23种设计模式之装饰器模式(结构型,2 Decorator,c++实现)
- "围观"设计模式(13)--结构型之装饰模式(Decorator Pattern)
- [导入]C#面向对象设计模式纵横谈(10):Decorator 装饰模式(结构型模式).zip(9.84 MB)
- PHP设计模式:结构型之装饰者(Decorator)
- 设计模式系列--Decorator
- 设计模式笔记-结构型模式之四--Decorator
- 设计模式(3)-结构型-装饰模式(Decorator)
- 设计模式--装饰器模式Decorator(结构型)
- [设计模式-结构型]装饰模式(Decorator)
- 经典设计模式1:结构型模式:DECORATOR——装饰模式
- 设计模式--Decorator---结构型
- 【设计模式】结构型模式之装饰器Decorator
- 设计模式随笔系列:来杯咖啡-装饰者模式(Decorator)[转]
- 设计模式(3)-结构型-装饰模式(Decorator)
- [设计模式-结构型]装饰模式(Decorator)
- 设计模式学习(结构型模式)—装饰模式(Decorator)
- 设计模式随笔系列:来杯咖啡-装饰者模式(Decorator)[转]
- Java IO 系列----流和Decorator设计模式
- 设计模式(四)装饰器模式Decorator(结构型)