我们经常会遇见,一些不想改变接口,希望在接口上边“加强”,像是给个装饰品一样,在接口方法名字和参数都不变的情况下添加新的增强的部分。这就涉及到一个装饰模式。
装饰模式实现以及用途哪里装饰模式体现的做突出,那一定是Java的IO类。因为涉及到太多的实现和子类,如果单纯的通过继承,估计各个子类里面的代码估计要爆炸了。
比如下面这个读取文件流的代码:
FileInputStream 是专门用来读取文件流的子类。BufferedInputStream 是一个支持带缓存功能的数据读取类,可以提高数据读取的效率
InputStream in = new FileInputStream("/user/zhangpeng/zp.txt");
InputStream bin = new BufferedInputStream(in);
byte[] data = new byte[128];
while (bin.read(data) != -1) {
//...
}
看一下InputStream
package java.io;
public abstract class InputStream implements Closeable {
private static final int MAX_SKIP_BUFFER_SIZE = 2048;
public InputStream() {
}
public abstract int read() throws IOException;
public int read(byte[] var1) throws IOException {
return this.read(var1, 0, var1.length);
}
FilterInputStream
public
class FilterInputStream extends InputStream {
BufferedInputStream
public
class BufferedInputStream extends FilterInputStream {
private static int DEFAULT_BUFFER_SIZE = 8192;
private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;
protected volatile byte buf[];
装饰模式的构成以及和代理模式的区别
说句实在话,看组成部分,实际上装饰模式和代理模式差不多,都是四个部分。
装饰模式与适配器模式:装饰模式与适配器模式有的地方会合在一起,叫做“包装模式”,但是实际二者互为逆操作。一个是我接口不变的条件下直接增强功能,比如说以前问你擅长什么,你只会“唱跳rap”,现在增强一下你还会“打篮球”。
适配器模式则是改变接口不改变功能,比如说有个老的类现在不要用了,要用新的来替代,但是第三方用的还是老的类的方法,解决方式就是改写老的类的方法,去兼容新的类的方法来实现,这样第三方无感知,也不需要去做替换兼容。
半透明这个也好理解,就是你继承了另一个类,但是你有你自己的方法,这些事你父类没有的,某种意义上这个接口是你自己独有的,你又是装饰模式,但是由于这个独有的,你和父类不一致,不算完全“透明”,所以叫半透明。
举个例子PushbackInputStream,他继承了FilterInputStream ,但是他有自己unread(),打破了非常理论理想化的装饰器模式(接口不变,功能增强)。



