在上篇适配器模式中提到在Java io中InputStreamReader更多是扮演是一个装饰器角色,给StreamDecoder加以装饰。为什么这么说呢,先看看什么是装饰器模式呢?
Decorator装饰器,就是动态地给一个对象添加一些额外的职责,就好比为房子进行装修一样。因此,装饰器模式具有如下的特征:
1.它必须具有一个装饰的对象。
2.它必须拥有与被装饰对象相同的接口。
3.它可以给被装饰对象添加额外的功能。
也就是保持接口,增强性能。
与适配器模式不同的是,适配器是实现另一个接口,使两个接口得到适配。装饰器是实现相同的一个接口,内部引用了被装饰类,实现相同的方法,给被装饰类的方法又增强了额外的功能。如下:
//共同的接口
public interface Sourcable {
public void operation();
}
//需要被装饰的原始类
public class Source implements Sourcable {
public void operation() {
System.out.println("原始类的方法");
}
//装饰器
public class Decorator1 implements Sourcable {
private Sourcable sourcable;
public Decorator1(Sourcable sourcable){
super();
this.sourcable=sourcable;
}
public void operation() {
System.out.println("第1个装饰器前");
sourcable.operation();
System.out.println("第1个装饰器后");
}
}
在回来看JavaIO中的InputStreamReader与StreamDecoder。两者都继承了Reader抽象父类,都有自己的read方法,而在InputStreamReader中引用了一个StreamDecoder实例对象,虽然在InputStreamReader中并未对StreamDecoder的read方法添加额外的功能,但它引用StreamDecoder使用了关键字final ,让StreamDecoder不可变,从某种意义上来说它扩展的功能就是让InputStreamReader读取输入流时,编码格式不变,所以在上篇文章才提到InputStreamReader更倾向于作为一个装饰器角色。
public class InputStreamReader extends Reader {
private final StreamDecoder sd;
public int read() throws IOException {
return sd.read();
}
}
public class StreamDecoder extends Reader {
····
private InputStream in;
···
public int read() throws IOException {
return this.read0();
}
private int read0() throws IOException {
Object var1 = this.lock;
synchronized(this.lock) {
if(this.haveLeftoverChar) {
this.haveLeftoverChar = false;
return this.leftoverChar;
} else {
char[] var2 = new char[2];
int var3 = this.read(var2, 0, 2);
switch(var3) {
case -1:
return -1;
case 0:
default:
assert false : var3;
return -1;
case 2:
this.leftoverChar = var2[1];
this.haveLeftoverChar = true;
case 1:
return var2[0];
}
}
}
}
}