装饰器模式 — Java IO

Java IO中含有众多的类,对于刚接触的人来说往往摸不清头脑。其实只要理清了它们之间的层次关系,就容易理解很多。

Java IO中涉及到装饰器模式(Decorator Pattern)与适配器模式(Adapter Pattern)。先上一张Java IO(字节流)系谱图。

可以看到,输入和输出基本是高度对称的。

上图并没有包括所有的IO类,随着 Java 版本的变化,可能有新的类逐渐加入到这个大家族中,也可能有原有的类被废弃(StringBufferInputStream已废弃)。


装饰器模式

InputStream 是输入流所有类的父类,由此产生了很多分支,每个分支的功能不同,比如 FileInputStream 用来读取文件信息、ByteArrayInputStream 允许将内存的缓冲区当做 InputStream 使用、SequenceStream 将两个或多个 InputStream 对象转换成单一的Inputstream。

这里我们重点关注 FilterInputStream,即装饰类,它的子类可以用来装饰其它类型的 InputStream。

比如现在我想读取C盘下的test.txt文件,我们会这样用:

FileInputStream f = new FileInputStream(new File(“c:/test.txt”));

现在我嫌读取的太慢了,想给它加个缓冲的功能,怎么办呢?只需要给它套上一层外壳即可。

BufferedInputStream f = new BufferedInputStream(new FileInputStream(new File(“c:/test.txt”)));

这里,BufferedInputStream 就相当于外壳。当然,你也可以同时用多个装饰器,每个装饰器都有特定的功能。就好比我想吃蛋糕,但你可以给蛋糕同时加上草莓、芒果、樱桃作为点缀。

为什么 FilterInputStream 有如此神奇的功效呢?这就是装饰者模式的功劳。装饰者模式结构如下:

InputStream 就是图中的 Component,FilterStream 就是图中的Decorator,它的子类就是 ConcreteDecoratorA、ConcreteDecoratorB、ConcreteDecoratorC 等,其它的类就是 ConcretComponent。

看一下 FilterInputStream 的构造器或许能更加了解这一点。

public class FilterInputStream extends InputStream {
    /**
     * The input stream to be filtered.
     */
    protected volatile InputStream in;
    
    protected FilterInputStream(InputStream in) {
        this.in = in;
    }
}

FilterInputStream 构造器可以接受任意一种形式的 InputStream。

以 BufferedInputStream 为例,它在构造器中调用了父类的构造器。

public class BufferedInputStream extends FilterInputStream {
    public BufferedInputStream(InputStream in) {
        this(in, DEFAULT_BUFFER_SIZE);
    }
    public BufferedInputStream(InputStream in, int size) {
        super(in);//调用父类构造器
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }
}

装饰者设计模式主要是利用多态,将子类对象作为参数传递,达到装饰的效果。如果不采用装饰者模式,而是采用继承结构,会造成类爆炸,假如有n种属性,那所有的搭配种类就有 2n 个。

这里讲的是 Java IO 中的字节流,除了字节流以外,还有字符流。字节流可以通过 InputStreamReader 或 OutputStreamWriter 转换成字符流,这就是所谓的适配器模式(参考文章:适配器模式)。

附上 Java IO 图

iO流
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值