女人常说男人喜新厌旧,只见新人笑,那闻旧人哭,但装饰模式(Decorator)却是一种结交新朋友不忘老朋友的设计模式,非常适合去古代当老公(现代是不行的,因为只能娶一个老婆了)。装饰模式的本质是每一个装饰对象都被保留一个被其装饰的对象,装饰对象在展示新功能时会同时去调用被其装饰的对象的同功能函数,通过如此层层包含调用(即装饰),形成一个类似链表的结构,接下来的介绍中,我们还会看到更多的类似链表结构的设计模式,比如职责链模式、状态模式。
       仍以《大话设计模式》一书中装饰模式的小菜穿衣的例子为例,来看看装饰模式是如何做到家里红旗不倒,外面彩旗飘飘的。小菜要去会妹子,临行前为了给妹子留个好印象,精选牛仔裤一条,然后搭上简约风T恤,装扮一新后出门,为了能够让小菜搭配任何衣服,使用装饰模式描述这一过程。
1、穿衣基类,只有一个函数Show(),显示穿的衣服

class CDress
{
public:
virtual ~CDress() {} virtual void Show()
{
printf("dressed boy.\n");
}
};

2、装饰类基类

class CFinery : public CDress
{
public:
CFinery() : m_poDress(NULL) {}
virtual ~CFinery() {} virtual void Show()
{
if (m_poDress)
{
m_poDress->Show();
}
} void Decorate(CDress* poCDress)
{
m_poDress = poCDress;
} private:
CDress* m_poDress;
};

3、T恤和牛仔裤的具体装饰类

class CTShirt : public	CFinery
{
public:
virtual ~CTShirt() {} void Show()
{
printf("Tshirt ");
CFinery::Show();
}
}; class CJeans : public CFinery
{
public:
virtual ~CJeans() {} void Show()
{
printf("Jeans ");
CFinery::Show();
}
};

这里需注意,装饰类对象的Show()函数在显示出本对象的装扮的同时,需要去调用装饰基类的Show()函数,以显示其被装饰对象的旧有装扮,即不能忘了老朋友。

4、装饰过程

int main(int argc, char* argv[])
{
CDress oCDress;
CTShirt oCTShirt;
CJeans oCJeans; oCTShirt.Decorate(&oCDress);
oCJeans.Decorate(&oCTShirt);
oCJeans.Show(); return 0;
}

通过装饰过程可以看出,oCJeans 对象装饰了 oCTShirt 对象,所以 oCJeans 调用 Show() 函数时会调用 oCTShirt 的 Show() 函数,oCTShirt 又装饰了 oCDress 对象,这时 oCTShirt 又会调用 oCDress 的 Show() 函数,有点类似递归,也有点类似链表的味道,当然我们知道递归需要有一个终结者的,不然就没完没了了,所以最后被装饰的对象 oCDress 是不在有任何装饰对象的。

同时,如果小菜的妹子不喜欢这套打扮风格了,说要小菜把T恤换成衬衫,这时我们只要新增一个衬衫装饰类 CShirt ,然后把 oCJeans 的装饰对象换成 CShirt 即可,这里可见,使用了装饰模式后,换衣服都方便灵活多了。

5、装饰模式的应用
         装饰模式适合在原有功能上增加了新功能,但是新功能被调用前/后仍需要调用原有功能的情况,特别适合功能一层一层的扩展,同时保持旧有功能的正常调用的场景。比如我们设计一个编辑框的控件类,最初只有编辑文字的功能,我们新增一个装饰类后,我们能编辑出彩色的文字,这时我们只需要设置控件的背景颜色,然后去调用旧的对象编辑文字功能即可。过一段时间老大提新要求了,要求这个编辑框控件要搞和谐社会,要屏蔽敏感词,这时我们再新增一个装饰类,增加建设和谐社会功能后,再去调用编辑彩色文字的装饰类。当然,我们还能灵活变动,搞和谐社会的装饰类为了不花哨,也可以直接装饰原来的编辑框控件类,抛弃中间搞彩色文字的过程。

大话设计模式C++版——装饰模式的更多相关文章

  1. 大话设计模式C++版——代理模式

    本篇开始前先发个福利,程杰的<大话设计模式>一书高清电子版(带目录)已上传至CSDN,免积分下载. 下载地址:http://download.csdn.net/detail/gufeng9 ...

  2. 大话设计模式C++版——工厂模式在COM中的典型应用

    上篇<大话设计模式C++版——抽象工厂模式>中,我们拯救世界未遂,留下小小的遗憾,本篇中我们将给出一个解决方案——COM组件技术,同时也顺便扯扯工厂模式在COM组件技术中的应用. 工厂模式 ...

  3. 大话设计模式C++版——抽象工厂模式

    前面说过,简单工厂模式是最基础的一种设计模式,那以工厂命名的设计模式就是23种设计模式中最多的一种,他们一脉相承,一步一步进化而来,这里就是其中的最后一种——抽象工厂模式(Abstract Facto ...

  4. 大话设计模式C++版——工厂方法模式

    工厂方法模式是以简单工厂模式为基础的,如果未了解简单工厂模式的同学可先浏览<大话设计模式C++版——简单工厂模式>.在简单工厂模式中,提到过简单工厂模式的缺陷,即违背了开发—封闭原则,其主 ...

  5. 大话设计模式C++版——表驱动法改造简单工厂

    上回<大话设计模式C++版——简单工厂模式>中指出了简单工厂模式的缺陷,即违背了开发—封闭原则,其主要原因是由于switch的判断结构的使用,使修改或添加新的对象时需要改动简单工厂类的代码 ...

  6. 大话设计模式C++版——简单工厂模式

    简单工厂模式应该是所有设计模式中最简单,也最基础的一种模式,以下是一个简单的采用工厂模式写一个加减法的计算器. 1.抽象接口类——依赖倒转原则(高层和底层都要依赖于抽象,针对接口编程) class I ...

  7. 大话设计模式C++版——原则和引言

    转贴请注明转自:http://blog.csdn.net/gufeng99/article/details/45832711 读程杰的<大话设计模式>有一段时间了,将其C#版的设计模式代码 ...

  8. 大话设计模式Python实现-装饰模式

    装饰模式(Decorator Pattern):动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. 下面是一个给人穿衣服的过程,使用装饰模式: #!/usr/bin/en ...

  9. 大话设计模式C++版——观察者模式

    观察者模式是一种类似于消息分发的模式,用于一个任务需要被多个对象监听的场景,或者成员对象需要反向通知类对象的情况,是一种很有用的设计模式.    这里以大话设计模式中的例子为例,办公室员工A.B.C在 ...

随机推荐

  1. jquery多次上传同一张图片

    $().reset(); wrap():$('p').wrap('div');===><div><p></p></div>; .closest() ...

  2. 20款风格独特的搜索框 PSD 设计素材免费下载

    搜索框是网站中的最常用的组件一直,但有时候,搜索框因为设计不够新颖容易被访客忽视.通过提高一个搜索框的外观设计,最终对整体的网页设计带来好的变化.这份列表将是一个很好的资源,尤其是对设计师.希望你会喜 ...

  3. jQuery原型方法first,last,eq,slice源码分析

    这4个方法中前3个方法很常用大家都见过,但是slice方法可能会以为是数组方法,其实slice也是jQuery的一个原型方法,只不过是底层方法是为其他方法服务的(更具体点是为eq方法服务的),首先还是 ...

  4. 电商CRM的痛点在哪里?

    观电商风云,风起云涌,如何寻找新客户及维护老客户,抢占市场,此时迫在眉睫.在大家所认为的CRM就是发发短信,发发邮件等形式去推送活动信息,但在三疯看来,做CRM的关键词是“互动”,而不是简单的促销. ...

  5. [原] SharePoint 2010 WebPart与Google地图系列 一:创建显示地图的WebPart

    摘要: 作为信息化先驱的产品SharePoint 2010竟然对GIS相关技术支持如此有限,试问现在哪个企业没有大量的项目需要结合Google地图来进行开发,单纯地从Google Javascript ...

  6. Hosting socket.io WebSocket apps in IIS using iisnode

    In this post I explain how to configure a socket.io node.js application to use of WebSockets when ho ...

  7. AFNetworking二次封装的那些事

    AFNetworking可是iOS网络开发的神器,大大简便了操作.不过网络可是重中之重,不能只会用AFNetworking.我觉得网络开发首先要懂基本的理论,例如tcp/ip,http协议,之后要了解 ...

  8. Mac wifi已打开但尚未连接到网络

    把网络偏好设置  里面的询问新网络 关闭了   然后  重启电脑  试一下  应该就可以了

  9. 【代码笔记】iOS-侧滑效果

    一,效果图. 二,工程图. 三,代码. AppDelegate.h #import <UIKit/UIKit.h> //加入头文件 #import "PPRevealSideVi ...

  10. UITableView相关知识点

    //*****UITableView相关知识点*****// 1 #import "ViewController.h" // step1 要实现UITableViewDataSou ...