【图解设计模式系列】The Decerator Pattern: 装饰器模式
装饰器模式又叫做包装模式(Wrapper)。装饰器模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
在以下情况下应该使用装饰器模式:
1.需要扩展一个类的功能,或给一个类增加附加责任
2.需要动态的给一个对象增加功能,这些功能可以再动态的撤销
3.需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使其继承关系变的不现实。
英文解释:
attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.
The decorator adds its own behavior either before and/or after delegating to the object it decorates to do the rest of the job.


装饰器模式中的角色有:
抽象组件角色:给出一个抽象接口,一规范准备接收附加责任的对象
具体组件角色:定义一个将要接收附加责任的类
装饰角色:持有一个组件对象的实例,并定义一个一个与抽象组件接口一致的接口。
具体装饰角色:负责给组件对象"贴上去"附加的责任。
实例
JDK中的部分流的实现就使用了装饰器模式,比如BufferedInputStream对InputStream进行了装饰,BufferedReader对Reader进行了装饰,对应的OutputStream和Write也分别被BufferedOutputStream和BufferedWriter装饰了。

下面以BufferedInputStream为例,来分析一下装饰者模式。
/*抽象组件角色*/
public abstract class InputStream implements Closeable {
public abstract int read() throws IOException;
}
/*具体组件角色*/
public class FileInputStream extends InputStream{
public int read() throws IOException {
Object traceContext = IoTrace.fileReadBegin(path);
int b = 0;
try {
b = read0();
} finally {
IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1);
}
return b;
}
}
/*抽象装饰器角色*/
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[], int off, int len) throws IOException {
return in.read(b, off, len);
}
}
/*具体装饰器角色*/
public class BufferedInputStream extends FilterInputStream {
protected volatile byte buf[];
public BufferedInputStream(InputStream in){
this(in, defaultBufferSize);
}
public synchronized int read() throws IOException {
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
}
BufferedInputStream是继承自FilterInputStream的具体的装饰器类,该类提供一个内存的缓冲区来保存输入流中的数据。这样就带有缓冲功能,提高文件读入的效率。
所以,我们通常以这样的形式来使用它们:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));

浙公网安备 33010602011771号