修饰器模式(day04)
修饰器设计模式
--最近我给女朋友买了一款可以更换外壳的手机。现在的外壳是红色的,假如我想用这款手机的时候,会更换成银灰色的外壳。但是我不能随意更换天线或者话筒,因为这些功能模块在手机生产的时候就已经被固定了。
在维基百科中的介绍是如此:
修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。
我们来解释一下这段话,有几个关键词“动态”和“对象”。
首先解释一下动态,Java多态的实现方式:重载和重写。
重载是就是动态绑定,或者说是运行时绑定,具体体现在只有运行的时候根据传的参数来决定运行的方法,而重写是编译时绑定,具体表现为一旦在子类中覆盖了父类的方法,编译后引用此方法时都只会指向子类的实现了。
而在修饰模式中也是通过一定编程的技巧来达到这个动态绑定的效果。
简单来说,修饰模式的设计核心是用一个修饰器类作为容器来包裹原来的类,一般将原来的类对象作为构造器参数传入。
这里想必大家也注意到了,是把类的对象作为参数传入,而不是类。这也是上面的关键词“对象”,修饰器修饰的是对象,而并非类。
至于为什么会引入修饰模式呢?稍微讨论一下,如果不使用修饰器模式的话:
那么假设A类是基类,你需要基于A类的基础上扩展十几种功能,而且这些功能的实现都要是不同的一个子类。你将可能出现需要实现一个功能就要实现一个新的子类,甚至当你需要有多重功能组合的时候,这些子类又将成倍增长,不仅仅是耦合度高,而且类的数量也会产生一种“类爆炸”的效应。
如果用修饰器的话,就相当于一把开枪声音很大的枪支,可以往上面套上消音器,这样它就扩展了消音的功能,而且摘下来之后又和原来的枪一样了。或者在工业上我们随处可以见到这样的东西,耳机、话筒(外置)。
其实对于写框架或者对Java特别熟悉的人,应该都知道Java IO也是遵循了修饰器的设计模式。
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException; import org.junit.Test; public class FileReader { @Test
public void test() {
java.io.FileReader fr;
BufferedReader br = null;
try {
String path = this.getClass().getResource("1.txt").getFile();
File f = new File(path);
fr = new java.io.FileReader(f);
br = new BufferedReader(fr);
String str = br.readLine();
System.out.println(str);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null)
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
可以看到上面这段代码 BufferedReader(修饰器容器)包裹了FileReader(原类)对象,扩展了缓存功能。
在Spring中有一个与BeanFactory接口一样使用很频繁的单词 FactoryBean,就是用到了修饰器模式和工厂模式来实现的。
也就是相对于BeanFactory这个IOC容器而言,FactoryBean是一个能产生或者修改对象产生bean的一个特殊bean。也就是根据不同的原料生成不同的产品。
关于FactoryBean等更理解之后再做讨论。
修饰器模式(day04)的更多相关文章
- python设计模式之修饰器模式
python设计模式之修饰器模式 无论何时我们想对一个对象添加额外的功能,都有下面这些不同的可选方法. [ ] 如果合理,可以直接将功能添加到对象所属的类(例如,添加一个新的方法) [ ] 使用组合 ...
- My.Ioc 代码示例——谈一谈如何实现装饰器模式,兼谈如何扩展 My.Ioc
装饰器模式体现了一种“组合优于继承”的思想.当我们要动态为对象增加新功能时,装饰器模式往往是我们的好帮手. 很多后期出现的 Ioc 容器都为装饰器模式提供了支持,比如说 Autofac.在 My.Io ...
- PHP设计模式之装饰器模式
装饰器模式:如果已有对象的部分内容或功能性发生改变,但是不需要修改原始对象的结构或不使用继承,动态的扩展一个对象的功能,则应该使用装饰器模式.简单点说:就是我们不应该去修改已有的类,而是通过创建另外一 ...
- java设计模式之 装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...
- java IO之 字符流 (字符流 = 字节流 + 编码表) 装饰器模式
字符流 计算机并不区分二进制文件与文本文件.所有的文件都是以二进制形式来存储的,因此, 从本质上说,所有的文件都是二进制文件.所以字符流是建立在字节流之上的,它能够提供字符 层次的编码和解码.列如,在 ...
- JAVA设计模式--装饰器模式
装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...
- javascript装饰器模式
装饰器模式 什么是装饰器 原名decorator 被翻译为装饰器 可以理解为装饰 修饰 包装等意 现实中的作用 一间房子通过装饰可以变得更华丽,功能更多 类似一部手机可以单独使用 但是很多人都愿意家个 ...
- 设计模式学习心得<装饰器模式 Decorator>
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...
- react中的hoc和修饰器@connect结合使用
在学习react-redux的时候,看到了修饰器这个新的属性,这个是es7的提案属性,很方便.于是我用@connect代替了connect(使用的时候需要配置,这里不赘述),省去了很多不必要的代码,但 ...
随机推荐
- Dom4j 添加 / 更新 / 删除 XML
1.获得文档 /** *1.获得解析流 *2.解析XML */ 2.添加 /** *1.获取父元素 *2.创建元素 *3.创建属性并添加到元素中 *4.元素添加到根节点 */ 3.更新 /** *1. ...
- Mysql中的 的 Cascade ,NO ACTION ,Restrict ,SET NULL
转载自:http://blog.163.com/inflexible_simple/blog/static/1676946842011616102543931/ 外键约束对子表的含义: 如果在父 ...
- MongoDB在win7下安装配置
1.在MongoDB官网下载最新版本,并且安装 2.解压后在MongoDB文件目录下创建data文件夹和log文件夹,并且在log文件夹中新建mongodb.log文件 3.新建一个配置文件mongo ...
- ie6里png图片不透明
ie6下img图片或背景图片为png时,图片变成了一片黑色: 图中的jquery-timepicker的两个黑方块和img就是由此原因引用的.解决方法:由Drew Diller提供,对img.back ...
- 菜鸟做HTML5小游戏 - 翻翻乐
记录下开放过程.做小游戏开发,又要跨平台,flash又不支持iPhone,html5是最好的选择. 先看看最后效果: 好了,开始demo. 1.准备工作: 图片素材(省略...最后代码一起打包) 了解 ...
- linux pc syncy安装问题
linux pc 上安装syncy遇到的坑 pycurl安装可以指定curl-config,这个是根据自己机器libcurl安装位置确定,不在默认位置时要指定:python setup.py inst ...
- ADT-位图
利用位图数据结构实现排序,利用每一位的下标作为索引,每位的值作为属性值,可以表示存在或不存在,适合存储稠密的数据,排序遍历的范围会是索引的最大值 最后发现耗时比python中list自带的sort多, ...
- 《VIM-Adventures攻略》 LEVEL 1-3
此文已转至http://cn.abnerchou.me/2014/03/04/e40e2146/ 上期有人提到此游戏烂尾.其实没有啦,作者是位"贪财"的主,不付费不给玩剩下的章节. ...
- dom4j解析xml字符串
import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.Docume ...
- hdu Number Sequence
这道题是寻找规律.别的方法一般都是超时. #include <cstdio> #include <cstring> #include <algorithm> usi ...