C++设计模式8--装饰模式(Decorator)--动态的增减功能

简介:

新奇的IPad

快到媳妇生日了,这几天加班加点的干活,给媳妇买了个IPadMini,可把媳妇乐坏了,媳妇拿到手第一天,就跑出去跟姐妹们得瑟了一把。

 

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class Pad  
  5. {  
  6. public:  
  7.     Pad(){ }  
  8.     virtual ~Pad(){ }  
  9.     virtual void Show( ) = 0;  
  10. };  
  11.   
  12. class IPad : public Pad  
  13. {  
  14. public :  
  15.     IPad( ){ }  
  16.     virtual ~IPad( ){  };  
  17.   
  18.     void Show( )  
  19.     {  
  20.         std::cout <<"新的Ipad Mini..." <<endl;  
  21.     }  
  22. };  
  23.   
  24. int main( )  
  25. {  
  26.     // 给媳妇买了一个IpadMini  
  27.     Pad *pad = new IPad( );  
  28.     pad->Show( );               // 跑出去得瑟一下  
  29.   
  30.     return 0;  
  31. }  

 弄个保护套

晚上回来,我问她,开心不,她说,开心是开心,但是朋友们都说怎么没给Pad弄个保护套,要不容易摔,摔坏了去维修可是很贵的,我嘻嘻一笑,容易直接上苹果店买了一个,走上路上美滋滋的。

 

  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. // pad类的抽象接口  
  5. class Pad  
  6. {  
  7. public:  
  8.     Pad(){ }  
  9.     virtual ~Pad(){ }  
  10.     virtual void Show( ) = 0;  
  11. };  
  12.   
  13. // 新的IPadMini  
  14. class IPad : public Pad  
  15. {  
  16. public :  
  17.     IPad( ){ }  
  18.     virtual ~IPad( ){  };  
  19.   
  20.     void Show( )  
  21.     {  
  22.         std::cout <<"新的Ipad Mini..." <<endl;  
  23.     }  
  24. };  
  25.   
  26. // 加了保护套的IPadMini  
  27. class CoverIPad : public IPad  
  28. {  
  29. public :  
  30.     CoverIPad( ){ }  
  31.     virtual ~CoverIPad( ){  };  
  32.   
  33.     void Show( )  
  34.     {  
  35.         std::cout <<"加了保护套的,新的Ipad Mini..." <<endl;  
  36.     }  
  37. };  
  38.   
  39.   
  40. int main( )  
  41. {  
  42.     // 现在我买了一个IpadMini  
  43.     Pad *pad = new CoverIPad( );  
  44.     pad->Show( );               // 跑出去得瑟一下  
  45.   
  46.   
  47. }  

还要个贴膜???

回家拿给媳妇看,媳妇说,老公能不能再给贴个膜啊 ,人家指甲长,万一把屏划花了怎么办呢呢,还有....(此处省略一万字),好吧再次出发,等等,难道要我在派生出一个CoverFoilIPad,天天这样子一天一个新的花样,这框架得多复杂,不行得换个方式。

我想想,直接弄装饰得了,那些保护套,贴膜什么的不都是装饰么。。

好了装饰模式出现了。

基础还是我们的Ipad,

  1. //公共抽象类  
  2. // 对应于 -=> 抽象构件(Component)角色  
  3. class Pad  
  4. {  
  5. public:  
  6.     Pad(){ }  
  7.     virtual ~Pad(){ }  
  8.     virtual void Show( ) = 0;  
  9. };  
  10.   
  11.   
  12. // 具体构件(Concrete Component)角色  
  13. class IPad : public Pad  
  14. {  
  15. public :  
  16.     IPad( ){ }  
  17.     virtual ~IPad( ){  };  
  18.   
  19.     void Show( )  
  20.     {  
  21.         std::cout <<"新的Ipad Mini..." <<endl;  
  22.     }  
  23. };  

下面是那些装饰,保护套,贴膜,管你是什么,爱来多少来多少,咱不怕

  1. // 装饰(Decorator)角色:  
  2. class Decorator : public Pad  
  3. {  
  4. public :  
  5.     Decorator(Pad *pad)  
  6.     {  
  7.         m_pad = pad;  
  8.     }  
  9.     virtual ~Decorator( ){ };  
  10.   
  11.     void Show( )  
  12.     {  
  13.         this->m_pad->Show( );       // 展示一下自己的手机  
  14.     }  
  15.   
  16. protected:  
  17.     Pad *m_pad;  
  18.   
  19.     virtual void AddDecorator( ) = 0;  
  20.   
  21. };  
  22.   
  23. // 具体装饰(Concrete Decorator)角色  
  24. class CoverDecorator : public Decorator  
  25. {  
  26. public :  
  27.     CoverDecorator(Pad *pad)  
  28.     :Decorator(pad)  
  29.     {  
  30.     }  
  31.   
  32.     virtual ~CoverDecorator( ){ }  
  33.   
  34.     void Show( )  
  35.     {  
  36.         this->AddDecorator( );  
  37.         Decorator::Show( );  
  38.     }  
  39.   
  40. protected:  
  41.     void AddDecorator( )  
  42.     {  
  43.         std::cout <<"弄了个保护套";  
  44.     }  
  45.   
  46. };  
  47.   
  48. // 具体装饰(Concrete Decorator)角色  
  49. class FoilDecorator : public Decorator  
  50. {  
  51. public :  
  52.     FoilDecorator(Pad *pad)  
  53.     :Decorator(pad)  
  54.     {  
  55.     }  
  56.     virtual ~FoilDecorator( ){ }  
  57.   
  58.     void Show( )  
  59.     {  
  60.         this->AddDecorator( );  
  61.         Decorator::Show( );  
  62.     }  
  63.   
  64. protected:  
  65.     void AddDecorator( )  
  66.     {  
  67.         std::cout <<"贴了个的贴膜,";  
  68.     }  
  69.   
  70. };  

下面看看媳妇怎么去得瑟的

  1. int main( )  
  2. {  
  3.     // 现在我买了一个IpadMini  
  4.     Pad *pad = new IPad( );  
  5.     pad->Show( );               // 跑出去得瑟一下  
  6.   
  7.     // 不行,还需要加个保护套  
  8.     Pad *coveDeco = new CoverDecorator(pad);  
  9.     coveDeco->Show( );               // 现在可以了吧,再出去得色一下  
  10.   
  11.     // 好吧,再来个贴膜  
  12.     Pad *foilDeco = new FoilDecorator(coveDeco);  
  13.     foilDeco->Show( );  
  14. }  

模式总结


概述

又叫装饰者模式。装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象


特点

①装饰对象和真实对象有相同的接口。这样客户端对象就可以和真实对象相同的方式和装饰对象交互。

② 装饰对象包含一个真实对象的引用(reference)

③ 装饰对象接受所有来自客户端的请求。它把这些请求转发给真实的对象。

④装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。

要点:

1. 装饰者和被装饰对象有相同的超类型。

2. 可以用一个或多个装饰者包装一个对象。

3. 装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。

4. 对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的用你喜欢的装饰者来装饰对象。

5. 装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是获得其行为。

6. 装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。在实际项目中可以根据需要为装饰者添加新的行为,做到“半透明”装饰者。

适用场景与优缺点:

在以下情况下应当使用装饰模式:

1.需要扩展一个类的功能,或给一个类增加附加责任。 

2.需要动态地给一个对象增加功能,这些功能可以再动态地撤销。 

3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

优点:

1. Decorator模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性。

2. 通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

缺点:

1. 这种比继承更加灵活机动的特性,也同时意味着更加多的复杂性。

2. 装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。

3. 装饰模式是针对抽象组件(Component)类型编程。但是,如果你要针对具体组件编程时,就应该重新思考你的应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。


转载:http://blog.csdn.net/gatieme/article/details/18034425

目录
打赏
0
0
0
0
248
分享
相关文章
4步实现C++插件化编程,轻松实现功能定制与扩展(2)
本文是《4步实现C++插件化编程》的延伸,重点介绍了新增的插件“热拔插”功能。通过`inotify`接口监控指定路径下的文件变动,结合`epoll`实现非阻塞监听,动态加载或卸载插件。核心设计包括`SprDirWatch`工具类封装`inotify`,以及`PluginManager`管理插件生命周期。验证部分展示了插件加载与卸载的日志及模块状态,确保功能稳定可靠。优化过程中解决了动态链接库句柄泄露问题,强调了采纳用户建议的重要性。
72 17
4步实现C++插件化编程,轻松实现功能定制与扩展(2)
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。
【实战指南】4步实现C++插件化编程,轻松实现功能定制与扩展
本文介绍了如何通过四步实现C++插件化编程,实现功能定制与扩展。主要内容包括引言、概述、需求分析、设计方案、详细设计、验证和总结。通过动态加载功能模块,实现软件的高度灵活性和可扩展性,支持快速定制和市场变化响应。具体步骤涉及配置文件构建、模块编译、动态库入口实现和主程序加载。验证部分展示了模块加载成功的日志和配置信息。总结中强调了插件化编程的优势及其在多个方面的应用。
834 77
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
77 5
C++是一种功能强大的编程语言,
C++是一种功能强大的编程语言,
98 14
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
【八】设计模式~~~结构型模式~~~装饰模式(Java)
文章详细介绍了装饰模式(Decorator Pattern),这是一种对象结构型模式,用于在不使用继承的情况下动态地给对象添加额外的职责。装饰模式通过关联机制,使用装饰器类来包装原有对象,并在运行时通过组合的方式扩展对象的行为。文章通过图形界面构件库的设计案例,展示了装饰模式的动机、定义、结构、优点、缺点以及适用场景,并提供了Java代码实现和应用示例。装饰模式提高了系统的灵活性和可扩展性,适用于需要动态、透明地扩展对象功能的情况。
【八】设计模式~~~结构型模式~~~装饰模式(Java)
Unity插件开发全攻略:从零起步教你用C++扩展游戏功能,解锁Unity新玩法的详细步骤与实战技巧大公开
【8月更文挑战第31天】Unity 是一款功能强大的游戏开发引擎,支持多平台发布并拥有丰富的插件生态系统。本文介绍 Unity 插件开发基础,帮助读者从零开始编写自定义插件以扩展其功能。插件通常用 C++ 编写,通过 Mono C# 运行时调用,需在不同平台上编译。文中详细讲解了开发环境搭建、简单插件编写及在 Unity 中调用的方法,包括创建 C# 封装脚本和处理跨平台问题,助力开发者提升游戏开发效率。
764 0

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等