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

 案例装饰器模式比较经典的应用就是 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 都各自进行相同的实现。

图片


更多相关文章

  1. Java并发原子类有哪些?如何使用?
  2. 和字节跳动面试官学长聊了聊人生~
  3. java多线程(11)AtomicBoolean原子类分析
  4. java中一个重要的原子类AtomicInteger详解(基于jdk1.8源码分析)
  5. 值得收藏的正则表达式(匹配中文字符、匹配双字节字符、匹配HTML标
  6. 我可以在运行PHP的64位系统上将PHP_INT_SIZE定义为4个字节吗?
  7. PHP字节单位转换
  8. curl POST的数据大于1024字节
  9. Windows上不可读的字节码数据库tar.gz(Maxmind)

随机推荐

  1. c语言结构化程序设计的三种基本结构是什
  2. c语言如何求n个数的平均值?
  3. c语言字符常量的合法表示形式是什么
  4. c语言规定,函数返回值的类型是由什么决定
  5. unsigned int几个字节
  6. c语言如何读取txt文件内容?
  7. c语言常量的正确表示方法有哪些
  8. c语言static关键字的作用是什么
  9. .net framework有什么用
  10. c语言求平方函数是什么