Java I/O - 装饰者模式
大约 2 分钟
Java I/O 中的设计模式(装饰)
提示
本文了解 Java 设计模式中的一种模式,装饰者模式,在 Java.io 包中的 包装流 中就使用了装饰者模式
如需了解装饰器模式详解请看👉 装饰器模式详解
装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构,装饰器模式中有四个重要的角色
- 抽象构件角色 (Component)
- 具体构件角色(ConcreteComponent)
- 抽象装饰者角色(Decorator)
- 具体装饰者角色(ConcreteDecorator)
以 InputStream 举例,它就是一个 抽象的构建角色(Component)
public abstract class InputStream implements Closeable {
// ...
}
且定义有抽象方法
public abstract int read() throws IOException;
public void close() throws IOException {}
该抽象方法由具体的子类去实现,直接继承了 InputStream,并且提供某一特定功能的子类有
- ByteArrayInputStream
- FileInputStream
- FilterInputStream
- PipedInputStream
- DataInputStream
这些子类都有自己特定的功能,FileInputStream 代表文件输入流,我们称这些子类为 具体构件角色(ConcreteComponent)
抽象装饰者(Decorator)
在这些类中有一个类和其他类不同 - FilterInputStream,查看其源代码可知,其内部维护了一个 InputStream 对象,并且它的所有方法,都是调用这个成员对象的同名方法,那么这个 FilterInputStream 就是一个抽象装饰者(Decorator)
public class FilterInputStream extends InputStream {
protected volatile InputStream in;
protected FilterInputStream(InputStream in) {
this.in = in;
}
public int read() throws IOException {
return in.read();
}
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
public int read(byte b[], int off, int len) throws IOException {
return in.read(b, off, len);
}
public long skip(long n) throws IOException {
return in.skip(n);
}
public int available() throws IOException {
return in.available();
}
public void close() throws IOException {
in.close();
}
public synchronized void mark(int readlimit) {
in.mark(readlimit);
}
public synchronized void reset() throws IOException {
in.reset();
}
public boolean markSupported() {
return in.markSupported();
}
}
FilterInputStream 类下面有它的一些子类,我们主要看常用的 BufferedInputStream 缓冲包装流,查看它的源代码
public class BufferedInputStream extends FilterInputStream {
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
}
查看它的 read() 方法源码可知,BufferedInputStream 就是一个具体的装饰者角色(ConcreteDecorator),它能为一个原本没有缓冲功能的 InputStream 添加上缓冲的功能,例如 FIleInputStream 并没有缓存功能,使用 BufferedInputStream 来装饰它,使得其具备缓存能力,提高程序的性能