Java程序员们应该对java.io对不会陌生,因为java.io包采用了装饰器模式。

一、定义:

Decorator装饰器,顾名思义,就是动态地给一个对象添加一些额外的职责,就好比为房子进行装修一样。因此,装饰器模式具有如下的特征:

它必须具有一个装饰的对象。

它必须拥有与被装饰对象相同的接口。

它可以给被装饰对象添加额外的功能。

用一句话总结就是:保持接口,增强性能。

装饰器通过包装一个装饰对象来扩展其功能,而又不改变其接口,这实际上是基于对象的适配器模式的一种变种。它与对象的适配器模式的异同点如下。

相同点:都拥有一个目标对象。

不同点:适配器模式需要实现另外一个接口,而装饰器模式必须实现该对象的接口。

二、 典型的装饰器模式的图:

三、相关实例:

1、 Sourcable接口定义了一个方法 operation() 。

  1. package pattern.decorator;
  2. public interface Sourcable {
  3. public void operation();
  4. }

2、 Source.java 是 Sourcable.java 的一个实现, operation() 方法的实现就是简单的负责往控制台输出一个字符串:

  1. package pattern.decorator;
  2. public class Source implements Sourcable {
  3. public void operation() {
  4. System.out.println("原始类的方法");
  5. }
  6. }

3、装饰器类 Decorator1.java 采用了典型的对象适配器模式,它首先拥有一个 Sourcable 对象 source ,该对象通过构造函 数进行初始化。然后它实现了 Sourcable.java 接口,以期保持与 source 同样的接口,并在重写的operation() 方法中调用  source 的 operation() 函数,在调用前后可以实现自己的输出,这就是装饰器所扩展的功能。

  1. package pattern.decorator;
  2. public class Decorator1 implements Sourcable {
  3. private Sourcable sourcable;
  4. public Decorator1(Sourcable sourcable){
  5. super();
  6. this.sourcable=sourcable;
  7. }
  8. public void operation() {
  9. System.out.println("第1个装饰器前");
  10. sourcable.operation();
  11. System.out.println("第1个装饰器后");
  12. }
  13. }

装饰器类Decorator2.java 是另一个装饰器,不同的是它装饰的内容不一样,即输出了不同的字符串。其源代码如

  1. package pattern.decorator;
  2. public class Decorator2 implements Sourcable {
  3. private Sourcable sourcable;
  4. public Decorator2(Sourcable sourcable){
  5. super();
  6. this.sourcable=sourcable;
  7. }
  8. public void operation() {
  9. System.out.println("第2个装饰器前");
  10. sourcable.operation();
  11. System.out.println("第2个装饰器后");
  12. }
  13. }

装饰器类Decorator3.java 是第三个装饰器,不同的是它装饰的内容不一样,即输出了不同的字符串。其源代码如程序

  1. package pattern.decorator;
  2. public class Decorator3 implements Sourcable {
  3. private Sourcable sourcable;
  4. public Decorator3(Sourcable sourcable){
  5. super();
  6. this.sourcable=sourcable;
  7. }
  8. public void operation() {
  9. System.out.println("第3个装饰器前");
  10. sourcable.operation();
  11. System.out.println("第3个装饰器后");
  12. }
  13. }

这时,我们就可以像使用对象的适配器模式一样来使用这些装饰器,使用不同的装饰器就可以达到不同的装饰效果。如下测试类:首先需要创建一 个源类对象 source ,然后根据将对象使用 Decorator1 来装饰,并以此使用Decorator2 、 Decorator3 进行装饰,装饰后的对象同样具有与 source 同样的接口。

  1. package pattern.decorator;
  2. public class DecoratorTest {
  3. /**
  4. * @param args
  5. */
  6. public static void main(String[] args) {
  7. Sourcable source = new Source();
  8. // 装饰类对象
  9. Sourcable obj = new Decorator1(new Decorator2(new Decorator3(source)));
  10. obj.operation();
  11. }
  12. }

运行该程序的输出如下:

第1 个装饰器装饰前

第2 个装饰器装饰前

第3 个装饰器装饰前

原始类的方法

第3 个装饰器装饰后

第2 个装饰器装饰后

第1 个装饰器装饰后

从输出的结果可以看出,原始类对象source 依次被 Decorator1 、 Decorator2 、 Decorator3 进行了装饰。

JAVA装饰器模式的更多相关文章

  1. Java 装饰器模式详解

    转载请注明出处:http://blog.csdn.net/zhaoyanjun6/article/details/56488020 前言 在上面的几篇文章中,着重介绍了Java 中常见的 IO 相关知 ...

  2. java 装饰器模式实现代码

    目录 1.实现装饰器模式 1.1.公共接口 1.2.接口实现 1.3.装饰器 1.4.装饰构件 1.5.测试装饰器 上图展示的是io流中的一个装饰者模式的代码结构 1.实现装饰器模式 汽车厂生产汽车实 ...

  3. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...

  4. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  5. Java设计模式07:常用设计模式之装饰器模式(结构型模式)

    1. Java之装饰器模式(Decorator Pattern) (1)概述:     装饰模式在Java种使用也很广泛,比如我们在重新定义按钮.对话框等时候,实际上已经在使用装饰模式了.在不必改变原 ...

  6. Java IO流以及装饰器模式在其上的运用

    流概述 Java中,流是一种有序的字节序列,可以有任意的长度.从应用流向目的地称为输出流,从目的地流向应用称为输入流. Java的流族谱 Java的 java.io 包中囊括了整个流的家族,输出流和输 ...

  7. java设计模式之七装饰器模式(Decorator)

    顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个接口,装饰对象持有被装饰对象的实例,关系图如下: Source类是被装饰类,Decorator类是一个 ...

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

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

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

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

随机推荐

  1. android开发的问题集(二)

    (1)子线程对UI线程操作的简便方法 子线程方法用 Looper.prepare(); 结束时候用 Looper.loop();  

  2. python Debug 单步调试

    一直犯愁的是python的调试,曾经写c都是编译完了用gdb直接调试了,轻松愉快.如今遇到这么一个解释型的程序.不知道怎么办了.用log吧,有时就是一个小程序,不想写这么多代码.打屏吧.有时屏幕翻得快 ...

  3. Android 基本控件

    http://www.cnblogs.com/LT-blogs/archive/2012/08/07/2626118.html http://blog.csdn.net/android_tutor/a ...

  4. C#整理6——数组的应用

    数组的应用:(一).冒泡排序.1.冒泡排序是用双层循环解决.外层循环的是趟数,里层循环的是次数.2.趟数=n-1:次数=n-趟数.3.里层循环使用if比较相临的两个数的大小,进行数值交换. 作业:1. ...

  5. 【 枚举 Enum 】循环 名称与值

      foreach (WeekDay c in (WeekDay [])Enum.GetValues(typeof(WeekDay ))) {Console.Write(String.Format(& ...

  6. IE6下a标签上发送ajax请求总是error

    IE6下真是处处是坑啊!!!走过了一个又一个坑,记录一下吧. 之前不知道a标签上注册click事件之后,发送ajax请求总是error.后来经过几番网上搜索,终于找到高人遇到此坑的解决办法.原来是a标 ...

  7. HTML5 canvas 绘制精美的图形

    HTML5 是一个新兴标准,它正在以越来越快的速度替代久经考验的 HTML4.HTML5 是一个 W3C “工作草案” — 意味着它仍然处于开发阶段 — 它包含丰富的元素和属性,它们都支持现行的 HT ...

  8. 手机不支持onchange事件

    今天,微信上用input type=date来计算日期,苹果上可以,我的小米2s手机死活不触发onchange,大三星的onchange效果怎么看都是onblur.听燕哥说,这事儿,得折腾. 搞来搞去 ...

  9. Java中两种实现多线程方式的对比分析

    本文转载自:http://www.linuxidc.com/Linux/2013-12/93690.htm#0-tsina-1-14812-397232819ff9a47a7b7e80a40613cf ...

  10. linux通过文件查找依赖关系

    通过文件查找安装包安装缺少libstdc++6这个文件在ls /usr/lib/libstd*下有两个文件/usr/lib/libstdc++.so.6 /usr/lib/libstdc++.so.6 ...