当提到Decorator(装饰者)模式的时候,都经常会提到java.io的设计模式。
作为一个灵活的,可扩展的类库,JDK中使用了大量的设计模式,对JDK中模式的研究不仅能增加对模式的理解,而且还有利于更透彻的了解类库的结构和组成。
在java.io包中,OutputStream,InputStream,Reader,Writer等都用到了Decorator模式。
Decorator模式简介:
Decorator模式又称Wrapper(包装器)模式,它用于给一个对象动态的添加一些额外的职责。
Component:被装饰对象的基类
定义对象的接口/抽象类,可以给这些对象动态增加职责
ConcreteComponent:具体被装饰的对象
定义具体的对象,Decorete可以为它增加额外的职责
Decorator:装饰者抽象类
维护一个指向Component实例的引用,并且定义了与Component一致的接口
ConcreteDecorator:具体装饰者
具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责
java.io包中OutputStream中的Decorator模式:
在java.io包中OutputStream是一个的Decorator模式的设计,OutputStream抽象类作为Decorator,BufferedOutputStream是ConcreteDecorator。
他们的关系如下图的UML图中示意:
其中OutputStream作为Component和Decorator,FilterOutputStream和BufferedOutputStream作为ConcreteDecorator。其中BufferedOutputStream也对FilterOutputStream做了具体的装饰,如flush()和write(int)方法。
OutputStream是一个抽象类,它是所有输出流的公共父类,其源代码如下:
package java.io;
public abstract class OutputStream implements Closeable, Flushable {
public abstract void write(int b) throws IOException;
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
if (b == null) {
throw new NullPointerException();
} else if ((off < 0) || (off > b.length) || (len < 0) ||
((off + len) > b.length) || ((off + len) < 0)) {
throw new IndexOutOfBoundsException();
} else if (len == 0) {
return;
}
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
public void flush() throws IOException {
}
public void close() throws IOException {
}
}
它定义了write(int b)的抽象方法。这相当于Decorator模式中的Component类。
FilterOutputStream是从OutputStream中继承的。
package java.io;
public class FilterOutputStream extends OutputStream {
protected OutputStream out;
public FilterOutputStream(OutputStream out) {
this.out = out;
}
public void write(int b) throws IOException {
out.write(b);
}
public void write(byte b[]) throws IOException {
write(b, 0, b.length);
}
public void write(byte b[], int off, int len) throws IOException {
if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
throw new IndexOutOfBoundsException();
for (int i = 0 ; i < len ; i++) {
write(b[off + i]);
}
}
public void flush() throws IOException {
out.flush();
}
public void close() throws IOException {
try {
flush();
} catch (IOException ignored) {
}
out.close();
}
}
FilterOutputStream中的protected OutputStream
out;属性相当于Decorator的Component。FilterOutputStream中并未真正给出write(int)的实现,而是调用out的write方法,flush()方法也同样。具体的write(int)方法和flush()方法是在BufferedOutputStream中实现的。
BufferedOutputStream的代码实现如下:
package java.io;
public
class BufferedOutputStream extends FilterOutputStream {
protected byte buf[];
protected int count;
public BufferedOutputStream(OutputStream out) {
this(out, 8192);
}
public BufferedOutputStream(OutputStream out, int size) {
super(out);
if (size <= 0) {
throw new IllegalArgumentException("Buffer size <= 0");
}
buf = new byte[size];
}
/** Flush the internal buffer */
private void flushBuffer() throws IOException {
if (count > 0) {
out.write(buf, 0, count);
count = 0;
}
}
public synchronized void write(int b) throws IOException {
if (count >= buf.length) {
flushBuffer();
}
buf[count++] = (byte)b;
}
public synchronized void write(byte b[], int off, int len) throws
IOException {
if (len >= buf.length) {
flushBuffer();
out.write(b, off, len);
return;
}
if (len > buf.length - count) {
flushBuffer();
}
System.arraycopy(b, off, buf, count, len);
count += len;
}
public synchronized void flush() throws IOException {
flushBuffer();
out.flush();
}
}
在BufferedOutputStream类中给出了flush()和write(int)的具体实现,是Decorator的具体装饰。
参考资料: