软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书,对于每个模式,用C++写了个小例子,加深一下理解。主要参考《大话设计模式》和《设计模式:可复用面向对象软件的基础》两本书。本文介绍装饰模式的实现。

装饰模式:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。有时我们希望给某个对象而不是整个类添加一些功能。比如有一个手机,允许你为手机添加特性,比如增加挂件、屏幕贴膜等。一种灵活的设计方式是,将手机嵌入到另一对象中,由这个对象完成特性的添加,我们称这个嵌入的对象为装饰。这个装饰与它所装饰的组件接口一致,因此它对使用该组件的客户透明。下面给出装饰模式的UML图。

在这种设计中,手机的装饰功能被独立出来,可以单独发展,进而简化了具体手机类的设计。下面给出Phone类的实现:

[cpp] view plaincopy print?
  1. //公共抽象类
  2. class Phone
  3. {
  4. public:
  5. Phone() {}
  6. virtual ~Phone() {}
  7. virtual void ShowDecorate() {}
  8. };

具体的手机类的定义:

[cpp] view plaincopy print?
  1. //具体的手机类
  2. class iPhone : public Phone
  3. {
  4. private:
  5. string m_name; //手机名称
  6. public:
  7. iPhone(string name): m_name(name){}
  8. ~iPhone() {}
  9. void ShowDecorate() { cout<<m_name<<"的装饰"<<endl;}
  10. };
  11. //具体的手机类
  12. class NokiaPhone : public Phone
  13. {
  14. private:
  15. string m_name;
  16. public:
  17. NokiaPhone(string name): m_name(name){}
  18. ~NokiaPhone() {}
  19. void ShowDecorate() { cout<<m_name<<"的装饰"<<endl;}
  20. };

装饰类的实现:

[cpp] view plaincopy print?
  1. //装饰类
  2. class DecoratorPhone : public Phone
  3. {
  4. private:
  5. Phone *m_phone;  //要装饰的手机
  6. public:
  7. DecoratorPhone(Phone *phone): m_phone(phone) {}
  8. virtual void ShowDecorate() { m_phone->ShowDecorate(); }
  9. };
  10. //具体的装饰类
  11. class DecoratorPhoneA : public DecoratorPhone
  12. {
  13. public:
  14. DecoratorPhoneA(Phone *phone) : DecoratorPhone(phone) {}
  15. void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }
  16. private:
  17. void AddDecorate() { cout<<"增加挂件"<<endl; } //增加的装饰
  18. };
  19. //具体的装饰类
  20. class DecoratorPhoneB : public DecoratorPhone
  21. {
  22. public:
  23. DecoratorPhoneB(Phone *phone) : DecoratorPhone(phone) {}
  24. void ShowDecorate() { DecoratorPhone::ShowDecorate(); AddDecorate(); }
  25. private:
  26. void AddDecorate() { cout<<"屏幕贴膜"<<endl; } //增加的装饰
  27. };

客户使用方式:

[cpp] view plaincopy print?
  1. int main()
  2. {
  3. Phone *iphone = new NokiaPhone("6300");
  4. Phone *dpa = new DecoratorPhoneA(iphone); //装饰,增加挂件
  5. Phone *dpb = new DecoratorPhoneB(dpa);    //装饰,屏幕贴膜
  6. dpb->ShowDecorate();
  7. delete dpa;
  8. delete dpb;
  9. delete iphone;
  10. return 0;
  11. }

装饰模式提供了更加灵活的向对象添加职责的方式。可以用添加和分离的方法,用装饰在运行时刻增加和删除职责。装饰模式提供了一种“即用即付”的方
法来添加职责。它并不试图在一个复杂的可定制的类中支持所有可预见的特征,相反,你可以定义一个简单的类,并且用装饰类给它逐渐地添加功能。可以从简单的部件组合出复杂的功能。[DP]

在本文的例子中,我们定义了两个具体的手机类,iPhone类和NokiaPhone类,通过单独的装饰类为它们添加特性,从而组合出复杂的功能。

设计模式C++实现(11)——装饰模式相关推荐

  1. Java设计模式(7)装饰模式(Decorator模式)

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...

  2. 设计模式-结构型模式-装饰模式

    设计模式-结构型模式-装饰模式 栗子 以成绩单需要家长签字为要求. 成绩单类图 // 抽象成绩单 public abstract class SchoolReport{// 成绩单你的成绩情况publ ...

  3. 设计模式之美-11| 实战一(下):如何利用基于充血模型的DDD开发一个虚拟钱包系统?

    十一.设计模式之美-11| 实战一(下):如何利用基于充血模型的DDD开发一个虚拟钱包系统? 一.钱包业务背景介绍 一个简单的钱包业务功能如下 1.充值 用户通过三方支付渠道,把自己银行卡账户内的钱, ...

  4. java设计模式学习笔记之装饰模式

    java设计模式学习笔记之装饰模式 尊重原创,转载请注明出处,原文地址: http://blog.csdn.net/qq137722697 这是一个使用策略模式和构建模式设计的网络请求框架,去看看吧& ...

  5. 11,装饰模式-孙悟空的六神装

    一,前言 7种结构型设计模式:桥接模式,适配器模式,装饰模式,组合模式,享元模式,外观模式,代理模式上篇我们说了外观模式:提供一个统一接口来访问子系统中的一群接口 外观定义了一个高层接口,让子系统更容 ...

  6. 对设计模式的总结之装饰模式与代理模式

    前言 面向对象编程追求的本质-提高扩展性.可维护性.灵活性和复用性.合理利用面向对象6个原则,能够很好的达到要求.如何利用好就是至关重要的了,前人总结了23+个设计模式能够让初学者更容易学到其中的精髓 ...

  7. 设计模式——代理模式与装饰模式的异同

    两种模式的特点 装饰模式: 在不改变接口的前提下,动态扩展对象的访问. 动态继承,让类具有在运行期改变行为的能力. 装饰模式,突出的是运行期增加行为,这和继承是不同的,继承是在编译期增加行为. 强调: ...

  8. Head First设计模式读书笔记三 装饰模式(个人理解:包装模式)

    本文示例代码材料源自Head First设计模式 以前整理自己整理的装饰模式的链接:https://blog.csdn.net/u011109881/article/details/58719049 ...

  9. 设计模式(七)装饰模式

    相关文章 设计模式(一)设计六大原则 设计模式(二)单例模式的七种写法 设计模式(三)建造者模式 设计模式(四)简单工厂模式 设计模式(五)观察者模式 设计模式(六)代理模式 1.装饰模式简介 装饰模 ...

  10. .NET中的设计模式——一步步发现装饰模式

    前言 过去我的一个朋友常说,学习任何编程语言最困难的部分是运行"Hello World",之后一切都很容易.多年以后,我才意识到他说的很对.学习设计模式的基本目标是要用它,尤其是帮 ...

最新文章

  1. 记录值上调10_「阴阳师」10月16日维护更新公告,海国迷踪,迷影重重
  2. [flite源码分析一]常用数据结构cst_val
  3. 从MySQL随机选取数据
  4. c语言怎样获得函数内参数的值_C语言可变参数函数的实现原理
  5. 机器学习笔记(十六):大规模机器学习
  6. Python 绘制热力图参数详解
  7. 游戏中的“战争黑雾”和现实中的程序员处境
  8. 常见网络命令整理(ping、trcert、netstat)
  9. oracle的nvl和nvl2是什么函数,两者区别
  10. app自动化之monkey测试
  11. 苹果笔记本安装完系统win10后多了osxreserved_Mac重装双系统,苹果笔记本电脑重装系统教程...
  12. iOS CNContactStore 与AddressBook
  13. Lenovo UEFI引导U盘 System x Install Windows Server 2016 R2
  14. python 伪造源ip_Python实现爬虫设置代理IP和伪装成浏览器的方法共享
  15. 浅谈APP运营推广:该如何的精准投放广告?
  16. 【欢迎来怼】 Beta发布事后诸葛亮会议
  17. 数据库为什么需要锁机制?有哪些锁机制?
  18. Nature Aging | 复旦大学冯建峰/程炜揭示每晚睡7小时刚刚好,睡过多或过少都有损大脑和心理健康...
  19. 没有SEO的DiscuzQ 值不值得站长选择?
  20. Elasticsearch-分布式搜索引擎介绍

热门文章

  1. Py之fvcore:fvcore库的简介、安装、使用方法之详细攻略
  2. DL之yolov3:使用yolov3算法时需要对Ubuntu系统进行配置的简介、过程步骤之详细攻略
  3. TF:基于CNN(2+1)实现MNIST手写数字图片识别准确率提高到99%
  4. AI:一个20年程序猿的学习资料大全—BAT等面试资料/NECCS大赛资料/一二级建造师/网络编程爬虫等/公务员——只有你不想要的,没有你找不到的
  5. 8.2 TensorFlow实现KNN与TensorFlow中的损失函数,优化函数
  6. java实体 和 xml相互转换
  7. 使用visualvm远程监控LINUX服务器JVM
  8. jquery 加法 乘法运算 精确计算函数
  9. C/C++宏定义中#与##区别 .
  10. linux 安装 redis3.0