之前已经看过装饰器模式,但是感觉不是很清晰,但是有一种情况下出的代码,一定是装饰器。

Widget* aWidget = new BorderDecorator(new BorderDecorator(new ScrollDecorator(new TextField( 80, 24 ))));

可以看到,层层嵌套,每个类都可以按照一定的顺序嵌套多次。

比如将顺序改为如下:

Widget* bWidget = new ScrollDecorator(new BorderDecorator(new ScrollDecorator(new TextField( 80, 24 ))));

出现的结果就会不一样,看一下完整的代码。

#include <iostream>using namespace std;/* Component (interface) */
class Widget {public: virtual void draw() = 0; virtual ~Widget() {}
}; /* ConcreteComponent */
class TextField : public Widget {private:                  int width, height;public:TextField( int w, int h ){ width  = w;height = h; }void draw() { cout << "文本框: " << width << ", " << height << '\n'; }
};/* Decorator (interface) */
class Decorator : public Widget {private:Widget* wid;       // reference to Widgetpublic:Decorator( Widget* w )  { wid = w; }void draw() { wid->draw(); }~Decorator() {delete wid;}
};/* ConcreteDecoratorA */
class BorderDecorator : public Decorator { public:BorderDecorator( Widget* w ) : Decorator( w ) { }void draw() {Decorator::draw();    cout << "   添加边框" << '\n'; }
};/* ConcreteDecoratorB */
class ScrollDecorator : public Decorator {
public:ScrollDecorator( Widget* w ) : Decorator( w ) { }void draw() {Decorator::draw(); cout << "   添加滚动" << '\n';}
};int main( void ) {Widget* aWidget = new BorderDecorator(new BorderDecorator(new ScrollDecorator(new TextField( 80, 24 ))));aWidget->draw();delete aWidget;Widget* bWidget = new ScrollDecorator(new BorderDecorator(new ScrollDecorator(new TextField( 80, 24 ))));bWidget->draw();delete bWidget;return 0;
}

看看运行结果:

可以给文本框动态的添加形态。

参考类图如下:

适用性:

以下情况使用Decorator模式

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

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

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

4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

优点:

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

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

缺点:

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

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

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

设计模式(6)-装饰器(认识程序中的装饰器)相关推荐

  1. vhdl八路抢答器简单程序_贵州抢答器plc程序编程图-云南尼邦商贸

    贵州抢答器plc程序编程图 应答设备装有使用嵌入式ppt设计的软件的新升级版本,该软件可以支持导入各种格式的问题库(文本文档,单词).问题将在几秒钟内导入.导入的问题以ppt模式直接显示,并且可以直接 ...

  2. 新时达万能协议操作器刷写程序可以定制操作器开启显示名字

    新时达万能协议操作器刷写程序可以定制操作器开启显示名字 发软件和程序.id=610374063703&

  3. python装饰器原理-python 中的装饰器及其原理

    装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...

  4. python装饰器-究竟什么是装饰器?python中的装饰器介绍

    在了解装饰器之前,我们需要知道什么闭包是什么鬼! 闭包:在一个函数内定义了一个函数f,并且这个函数f引用外部变量,在把这个函数f当做返回值返回. 上述说了闭包的三个条件: 1.函数内定义了一个函数f ...

  5. java 反复器_java集合类中的枚举器(反复器)

    在任何集合类中,必须通过某种方法在其中置入对象,再用另一种方法从中取得对象.毕竟,容纳各种各样的对象正是集合的首要任务.在Vector中,addElement()便是我们插入对象采用的方法,而elem ...

  6. java web 过滤器 拦截器 监听器_Java中的拦截器和过滤器,可不是同一个东西

    过滤器(Filter) 过滤器就如上面的水质过滤器一样,把管道中的水进行一遍过滤再使用.过滤器基于filter接口中的doFilter回调函数,主要的用途是设置字符集.控制权限.控制转向.做一些业务逻 ...

  7. webpack 中的加载器简介||webpack 中加载器的基本使用——1. 打包处理 css 文件 2. 打包处理 less 文件 3.打包处理 scss 文件

    webpack 中的加载器 1. 通过 loader 打包非 js 模块 在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块,其他非 .js 后缀名结尾的模块, webpa ...

  8. java8收集器,Java 8中的收集器collectionAndThen()方法

    collectingAndThen()Java Collectors类中的方法使Collector适应于执行其他完成转换.它返回执行下游收集器动作的收集器,然后执行附加的结束步骤. 语法如下.stat ...

  9. linux播放器安装程序,MplayerLinux下多媒体播放器安装

    都说Mplayer是Linux下最好的多媒体播放器之一,所以我刚把显示和声卡整好就决心装个这个东东,最后终于在老红帽上装成功了. 下面的安装步骤就是参考众多老鸟的文章及自己N次失败实践出来的,仅供初学 ...

最新文章

  1. 物联网成网络安全防护新重点!
  2. mysql 中的like查找不忽略大小写
  3. echarts柱状图显示百分比_Echarts 饼状图显示信息,内容,值,百分比都显示的代码 更改图例等问题汇总...
  4. phpstudy-5.6.27-nts  安装redis扩展
  5. c++ 数组的输入遇到特定字符停止输入_C语言 第4章-字符串和格式化输入/输出
  6. ios加载本地html懒加载图片方案,IOS开发中加载大量网络图片优化方法
  7. SQL性能健康检查脚本
  8. [Spring实战系列](19)Servlet不同版本之间的区别
  9. netconsole 重定向kernel日志到远程服务器
  10. Verilog语言生成4位伪随机码
  11. 高数基础_第1节_概述以及预备知识
  12. intellij idea 插件 开发 新加的mainmenu不显示
  13. 计算机组成原理输入输出系统——DMA方式
  14. python+opencv实现图像拼接
  15. python画四叶草代码-python学习
  16. Flink电商指标分析项目(1)_项目整体工程搭建
  17. STEP2——《数据分析:企业的贤内助》重点摘要笔记(二)——数据获取资源...
  18. 关于vega打不开的问题
  19. 【chrome】chrome百度网盘网页版倍速
  20. String.getBytes()

热门文章

  1. 微信小程序勾选协议与提交按钮联动
  2. 2021-01-22 使用 Docker 打包 Python 项目
  3. 从上往下 流式布局_揭秘做好网站结构优化的4步(下)
  4. c语言系统主函数流程图,C语言程序设计——成语学习系统
  5. python实现第一个web_我的第一个python web开发框架(6)——第一个Hello World
  6. linux中lvs命令详解,LVS之三:ipvsadm常用管理命令介绍 | 旺旺知识库
  7. 伪共享(false sharing),并发编程无声的性能杀手
  8. git Rebase 变基 教程
  9. MySQL事务隔离级别详解
  10. (十)装饰器模式详解(与IO不解的情缘)