装饰器模式在开源代码中的应用

装饰器模式的作用:动态的给对象增加一些职责,即增加其额外的功能。

 

案例

装饰器模式比较经典的应用就是 JDK 中的 java.io 包下,InputStream、OuputStream、Reader、Writer 及它们的子类。

以 InputStream 为例

  • FileInputStream 是 InputStream 的子类,用来读取文件字节流
  • BufferedInputStream 是 InputStream 的子类的子类,可缓存的字节流
  • DataInputStream 也是 InputStream 的子类的子类,可直接读取 Java 基本类型的字节流

如果希望提供一个可以读取文件 + 可缓存的字节流,使用继承方式,就需要派生 FileBufferedInputStream;

如果希望提供一个可以读取文件 + 直接读取基本类型的字节流,使用继承方式,就需要派生 FileDataInputStream。

字节流功能的增强还包括支持管道 pipe、字节数组 bytearray、字节对象 object、字节流字符流的转换 等维度,如果用继承方式,那类的层级与种类会多到爆炸。

为了解决问题,这边就使用了装饰器模式。

 

InputStream 源码简化

public abstract class InputStream implements Closeable {
    public int read(byte b[], int off, int len) throws IOException {}
}

 

FileInputStream 源码简化

public class FileInputStream extends InputStream {
    public FileInputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null);
    }

    public int read(byte b[], int off, int len) throws IOException {
        return readBytes(b, off, len);
    }
}

 

BufferedInputStream 源码精简,继承自 FilterInputStream ,改为 InputStream

public class BufferedInputStream extends InputStream {
    protected volatile InputStream in;

    public BufferedInputStream(InputStream in) {
        this.in = in;
    }

    public synchronized int read(byte b[], int off, int len) throws IOException {
    ...
    }
}

 

DataInputStream 源码精简,继承自 FilterInputStream ,改为 InputStream

public class DataInputStream extends InputStream {
    protected volatile InputStream in;

    public DataInputStream(InputStream in) {
        this.in = in;
    }

    public final int read(byte b[], int off, int len) throws IOException {
        return in.read(b, off, len);
    }

}

 

组合各种类型的字节流,使用

//读取文件 + 可缓存的字节流
new BufferedInputStream(new FileInputStream("E:/a.txt"));

//读取文件 + 直接读取基本类型的字节流
new DataInputStream(new FileInputStream("E:/a.txt"));

 

装饰器模式有两个特点:

  • 装饰器类和原始类继承同样的父类,可以通过构造方法对原始类“嵌套”多个装饰器类
  • 装饰器类是对功能的增强

 

PS:BufferedInputStream、DataInputStream 都继承自 FilterInputStream,FilterInputStream 对 InputStream 进行了公共实现,避免 BufferedInputStream、DataInputStream 都各自进行相同的实现。

 

 


【Java学习资源】整理推荐

  • 装饰器模式在开源代码中的应用
  • 桥接模式在开源代码中的应用
  • 适配器模式在开源代码中的应用
  • 代理模式在开源代码中的应用
  • 原型模式在开源代码中的应用
  • 建造者模式在开源代码中的应用
  • 工厂模式在开源代码中的应用
  • 单例模式在开源代码中的应用
  • 编码规范
  • 设计模式
  • 重构
  • 设计原则
  • 面向对象到底是什么
  • 代码质量有哪些评判标准?

 

 


【Java面试题与答案】整理推荐

  • 基础与语法
  • 集合
  • 网络编程
  • 并发编程
  • Web
  • 安全
  • 设计模式
  • 框架
  • 算法与数据结构
  • 异常
  • 文件解析与生成
  • Linux
  • MySQL
  • Oracle
  • Redis
  • Dubbo

 

你可能感兴趣的:(装饰器模式在开源代码中的应用)