前言
最近在学习IO 这块内容,结合经典的装饰模式,说下IO库中体现的设计模式。
正文
节点流和处理流
Java 中的流按照流的流向来分,可以分为输入流和输出流;按照流的角色分,可以分为节点流(低级流)和处理流(高级流),节点流是指 程序直接连到实际的数据源,和实际的输入、输出节点连接;处理流是对一个已经存在的流进行连接和封装,实际上是用处理流来包装节点流,既可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入/输出功能。因此处理流也被称为包装流。
Java 使用节点流来包装节点流是一种典型的装饰器设计模式。
Java IO 的结构介绍
对应的UML模型:
源码实现
/*****************InputStream类(抽象组件)***************/
package java.io;
public abstract class InputStream implements Closeable {
// MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
// use when skipping.
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
//……
public abstract int read() throws IOException;
}
/*****************FilterInputStream类(抽象装饰者)***************/
package java.io;
public
class FilterInputStream extends InputStream {
/**
* The input stream to be filtered.
*/
protected volatile InputStream in;
//将抽象组件作为参数放在构造函数中,接受一个抽象组件对象
protected FilterInputStream(InputStream in) {
this.in = in;
}
}
/*****************BufferedInputStream类(具体装饰者一)***************/
package java.io;
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
public class BufferedInputStream extends FilterInputStream {
private static int DEFAULT_BUFFER_SIZE = 8192;
public BufferedInputStream(InputStream in) {
this(in, DEFAULT_BUFFER_SIZE);
}
public BufferedInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
}
/*****************PushbackInputStream类(具体装饰者二)***************/
package java.io;
public class PushbackInputStream extends FilterInputStream {
public PushbackInputStream(InputStream in) {
this(in, 1);
}
public PushbackInputStream(InputStream in, int size) {
super(in);
if (size <= 0) {
throw new IllegalArgumentException("size <= 0");
}
this.buf = new byte[size];
this.pos = size;
}
}
/*****************FileInputStream类(具体组件/具体被装饰者)***************/
package java.io;
import java.nio.channels.FileChannel;
import sun.nio.ch.FileChannelImpl;
public class FileInputStream extends InputStream
{
public int read() throws IOException {
return read0();
}
private native int read0() throws IOException;
}
说明:此处介绍的只是java.IO包中四大等级结构InputStream 中的一种,其它体系内部也实现了装饰者模式,有兴趣的话可以对应着去看看。
总结
IO 体系中InputStream,outputStream,InputStreamReader,outputStreamReader各个体系内部用到的是装饰者模式,而outputStream和outputStreamReader之间用的是适配器模式,具体内容请看下一篇博客。