修饰器设计模式

--最近我给女朋友买了一款可以更换外壳的手机。现在的外壳是红色的,假如我想用这款手机的时候,会更换成银灰色的外壳。但是我不能随意更换天线或者话筒,因为这些功能模块在手机生产的时候就已经被固定了。


在维基百科中的介绍是如此:

修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。

我们来解释一下这段话,有几个关键词“动态”和“对象”。

首先解释一下动态,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)的更多相关文章

  1. python设计模式之修饰器模式

    python设计模式之修饰器模式 无论何时我们想对一个对象添加额外的功能,都有下面这些不同的可选方法. [ ] 如果合理,可以直接将功能添加到对象所属的类(例如,添加一个新的方法) [ ] 使用组合 ...

  2. My.Ioc 代码示例——谈一谈如何实现装饰器模式,兼谈如何扩展 My.Ioc

    装饰器模式体现了一种“组合优于继承”的思想.当我们要动态为对象增加新功能时,装饰器模式往往是我们的好帮手. 很多后期出现的 Ioc 容器都为装饰器模式提供了支持,比如说 Autofac.在 My.Io ...

  3. PHP设计模式之装饰器模式

    装饰器模式:如果已有对象的部分内容或功能性发生改变,但是不需要修改原始对象的结构或不使用继承,动态的扩展一个对象的功能,则应该使用装饰器模式.简单点说:就是我们不应该去修改已有的类,而是通过创建另外一 ...

  4. java设计模式之 装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构. 这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...

  5. java IO之 字符流 (字符流 = 字节流 + 编码表) 装饰器模式

    字符流 计算机并不区分二进制文件与文本文件.所有的文件都是以二进制形式来存储的,因此, 从本质上说,所有的文件都是二进制文件.所以字符流是建立在字节流之上的,它能够提供字符 层次的编码和解码.列如,在 ...

  6. JAVA设计模式--装饰器模式

    装饰器模式 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰 ...

  7. javascript装饰器模式

    装饰器模式 什么是装饰器 原名decorator 被翻译为装饰器 可以理解为装饰 修饰 包装等意 现实中的作用 一间房子通过装饰可以变得更华丽,功能更多 类似一部手机可以单独使用 但是很多人都愿意家个 ...

  8. 设计模式学习心得<装饰器模式 Decorator>

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...

  9. react中的hoc和修饰器@connect结合使用

    在学习react-redux的时候,看到了修饰器这个新的属性,这个是es7的提案属性,很方便.于是我用@connect代替了connect(使用的时候需要配置,这里不赘述),省去了很多不必要的代码,但 ...

随机推荐

  1. Sicily 2005.Lovely Number

    题目地址:2005.Lovely Number 思路: 若测试数据出现的次数为奇数,则输出它. 所以,可以先排序,若前后相等,前后都设为0,最后不为0的则可以输出. 具体代码如下: #include ...

  2. css3画苹果logo

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  3. 数学函数类方法的使用.java

    public class Test { public static void main(String[] args) { double a=2,b=3; double z1=Math.pow(a,b) ...

  4. IIS自定义404错误页显示“系统找不到指定的文件”解决方法

    在IIS站点属性里面设置了自定义的404错误页面为一个文件之后,有时一直不生效,总是提示这样一句话:“系统找不到指定的文件”. 其实这种错误也只是在某些网站程序中出现,其实解决办法很简单.这是由于II ...

  5. Git学习笔记01--初始化设置

    1.查看git版本 $ git --version 2.设置用户姓名和邮箱 $ git config --global user.name “Craftor” $ git config --globa ...

  6. 更新项目经常使用的Linux命令

    在公司经常在服务器上更新项目,总结了自己经常使用的命令: 1.删除:rm -rf 文件名2.复制:copy 文件 目标地址3.压缩:zip -r 压缩后文件名 被压缩目录4.移动:move 文件 目标 ...

  7. 被误解的 MVC 和被神化的 MVVM

    被误解的 MVC 和被神化的 MVVM 被误解的 MVC MVC 的历史 MVC,全称是 Model View Controller,是模型 (model)-视图 (view)-控制器 (contro ...

  8. js限制input只能输入有效的数字,有且只有一个小数点,第一个不能为小数点-备

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. 关于开源中文搜索引擎架构coreseek中算法详解

     Coreseek 是一款中文全文检索/搜索软件,以GPLv2许可协议开源发布,基于Sphinx研发并独立发布,专攻中文搜索和信息处理领域,适用于行业/垂直搜索.论坛/站内搜索.数据库搜索.文档/文献 ...

  10. SaltStack运行任务卡住了,怎么办?

    将相关的JOB ID杀死即可. salt-run jobs.active salt "*" saltutil.signal_job JOBID 15