装饰器模式的典型应用:java IO
InputStream in = new FileInputStream("/user/wangzheng/test.txt");
InputStream bin = new BufferedInputStream(in);
byte[] data = new byte[128];
while (bin.read(data) != -1) {
//...
}
InputStream
是一个抽象类,FileInputStream
是专门用来读取文件流的子类。BufferedInputStream
是一个支持带缓存功能的数据读取类,可以提高数据读取的效率。- 流程:先创建一个
FileInputStream
对象,然后再传递给BufferedInputStream
对象来使用。
组合形式太多,无法直接设计一个综合类
继承 InputStream
的子类有很多。我们需要给每一个 InputStream
的子类,再继续派生支持某个功能的子类。
如果对功能进行其他方面的增强,会导致组合爆炸,类继承结构变得无比复杂,代码既不好扩展,也不好维护。因此不推荐使用继承。
将继承关系改为组合关系,
public abstract class InputStream {
//...
public int read(byte b[]) throws IOException {
return read(b,0,b.length);
}
public int read(byte b[],int off,int len) throws IOException {
//...
}
public long skip(long n) throws IOException {
//...
}
public int available() throws IOException {
return 0;
}
public void close() throws IOException {}
public synchronized void mark(int readlimit) {}
public synchronized void reset() throws IOException {
throw new IOException("mark/reset not supported");
}
public boolean markSupported() {
return false;
}
}
public class BufferedInputStream extends InputStream {
protected volatile InputStream in;
protected BufferedInputStream(InputStream in) {
this.in = in;
}
//...实现基于缓存的读数据接口...
}
public class DataInputStream extends InputStream {
protected volatile InputStream in;
protected DataInputStream(InputStream in) {
this.in = in;
}
//...实现读取基本类型数据的接口
}
- 装饰器类和原始类继承同样的父类,这样我们可以对原始类嵌套多个装饰器类。如:
InputStream in = new FileInputStream("/user/wangzheng/test.txt");
InputStream bin = new BufferedInputStream(in);
DataInputStream din = new DataInputStream(bin);
int data = din.readInt();
嵌套2个装饰器类:BufferedInputStream
和 DataInputStream
,让它既支持缓存读取,又支持按照基本数据类型来读取数据。
- 装饰器类是对功能的增强。
// 代理模式的代码结构(下面的接口也可以替换成抽象类)
public interface IA {
void f();
}
public class A impelements IA {
public void f() { //... }
}
public class AProxy impements IA {
private IA a;
public AProxy(IA a) {
this.a = a;
}
public void f() {
// 新添加的代理逻辑
a.f();
// 新添加的代理逻辑
}
}
// 装饰器模式的代码结构(下面的接口也可以替换成抽象类)
public interface IA {
void f();
}
public class A impelements IA {
public void f() { //... }
}
public class ADecorator impements IA {
private IA a;
public ADecorator(IA a) {
this.a = a;
}
public void f() {
// 功能增强代码
a.f();
// 功能增强代码
}
}