设计模式(6)-装饰器(认识程序中的装饰器)
之前已经看过装饰器模式,但是感觉不是很清晰,但是有一种情况下出的代码,一定是装饰器。
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)-装饰器(认识程序中的装饰器)相关推荐
- vhdl八路抢答器简单程序_贵州抢答器plc程序编程图-云南尼邦商贸
贵州抢答器plc程序编程图 应答设备装有使用嵌入式ppt设计的软件的新升级版本,该软件可以支持导入各种格式的问题库(文本文档,单词).问题将在几秒钟内导入.导入的问题以ppt模式直接显示,并且可以直接 ...
- 新时达万能协议操作器刷写程序可以定制操作器开启显示名字
新时达万能协议操作器刷写程序可以定制操作器开启显示名字 发软件和程序.id=610374063703&
- python装饰器原理-python 中的装饰器及其原理
装饰器模式 此前的文章中我们介绍过装饰器模式: 装饰器模式中具体的 Decorator 实现类通过将对组建的请求转发给被装饰的对象,并在转发前后执行一些额外的动作来修改原有的部分行为,实现增强 Com ...
- python装饰器-究竟什么是装饰器?python中的装饰器介绍
在了解装饰器之前,我们需要知道什么闭包是什么鬼! 闭包:在一个函数内定义了一个函数f,并且这个函数f引用外部变量,在把这个函数f当做返回值返回. 上述说了闭包的三个条件: 1.函数内定义了一个函数f ...
- java 反复器_java集合类中的枚举器(反复器)
在任何集合类中,必须通过某种方法在其中置入对象,再用另一种方法从中取得对象.毕竟,容纳各种各样的对象正是集合的首要任务.在Vector中,addElement()便是我们插入对象采用的方法,而elem ...
- java web 过滤器 拦截器 监听器_Java中的拦截器和过滤器,可不是同一个东西
过滤器(Filter) 过滤器就如上面的水质过滤器一样,把管道中的水进行一遍过滤再使用.过滤器基于filter接口中的doFilter回调函数,主要的用途是设置字符集.控制权限.控制转向.做一些业务逻 ...
- webpack 中的加载器简介||webpack 中加载器的基本使用——1. 打包处理 css 文件 2. 打包处理 less 文件 3.打包处理 scss 文件
webpack 中的加载器 1. 通过 loader 打包非 js 模块 在实际开发过程中,webpack 默认只能打包处理以 .js 后缀名结尾的模块,其他非 .js 后缀名结尾的模块, webpa ...
- java8收集器,Java 8中的收集器collectionAndThen()方法
collectingAndThen()Java Collectors类中的方法使Collector适应于执行其他完成转换.它返回执行下游收集器动作的收集器,然后执行附加的结束步骤. 语法如下.stat ...
- linux播放器安装程序,MplayerLinux下多媒体播放器安装
都说Mplayer是Linux下最好的多媒体播放器之一,所以我刚把显示和声卡整好就决心装个这个东东,最后终于在老红帽上装成功了. 下面的安装步骤就是参考众多老鸟的文章及自己N次失败实践出来的,仅供初学 ...
最新文章
- 物联网成网络安全防护新重点!
- mysql 中的like查找不忽略大小写
- echarts柱状图显示百分比_Echarts 饼状图显示信息,内容,值,百分比都显示的代码 更改图例等问题汇总...
- phpstudy-5.6.27-nts 安装redis扩展
- c++ 数组的输入遇到特定字符停止输入_C语言 第4章-字符串和格式化输入/输出
- ios加载本地html懒加载图片方案,IOS开发中加载大量网络图片优化方法
- SQL性能健康检查脚本
- [Spring实战系列](19)Servlet不同版本之间的区别
- netconsole 重定向kernel日志到远程服务器
- Verilog语言生成4位伪随机码
- 高数基础_第1节_概述以及预备知识
- intellij idea 插件 开发 新加的mainmenu不显示
- 计算机组成原理输入输出系统——DMA方式
- python+opencv实现图像拼接
- python画四叶草代码-python学习
- Flink电商指标分析项目(1)_项目整体工程搭建
- STEP2——《数据分析:企业的贤内助》重点摘要笔记(二)——数据获取资源...
- 关于vega打不开的问题
- 【chrome】chrome百度网盘网页版倍速
- String.getBytes()
热门文章
- 微信小程序勾选协议与提交按钮联动
- 2021-01-22 使用 Docker 打包 Python 项目
- 从上往下 流式布局_揭秘做好网站结构优化的4步(下)
- c语言系统主函数流程图,C语言程序设计——成语学习系统
- python实现第一个web_我的第一个python web开发框架(6)——第一个Hello World
- linux中lvs命令详解,LVS之三:ipvsadm常用管理命令介绍 | 旺旺知识库
- 伪共享(false sharing),并发编程无声的性能杀手
- git Rebase 变基 教程
- MySQL事务隔离级别详解
- (十)装饰器模式详解(与IO不解的情缘)