Java中IO体系字节流与字符流之适配器模式

时间:2021-08-08 22:42:48

在java 的IO体系中,除了常用到的装饰模式外,还有一个常用的设计模式:适配器设计模式,主要用来实现字节流和字符流类的适配转换工作。相比装饰模式而言,适配器模式就相对简单多了,完成一个适配器模式需要三个组件:目标接口(也就是最终要调用的对象的类型)Target,需要被适配的类(也就是真正需要调用能力拥有者的类)Adaptee,适配器者Adapter(就是把Adaptee的能力填充到Target接口里面的类,Adapter一般继承于或实现Target),文字说明有点复杂,举个例子就明白了

Target:

Public class Target{

Public void fun(){};

}

Adaptee:

Public class Adaptee {

Public void realFun(){System.out.println(“itis real fun”);}

}

Adapter:

Public class Adapte extends Target{

Adaptee  adaptee = new Adaptee();

Public void fun(){

Adaptee. realFun();

}

}

--上面就是整个适配器模式实现的例子了,客户端使用时:

Target target = new Adapter ();

Target. fun();

执行结果:it is real fun

就是这么简单,说白了就是组合模式,任何设计模式中出现某个类使用其他类的能力,不管怎么吹,什么设计模式高大上名词一大堆,归根结底离不开继承和组合两种模式。而继承比较明显简单,所以很多设计模式就是变着花样使用组合模式。组合与多态的花样结合制造出了很多的“设计模式”。

 

说完适配器模式原理后,看看字符流是如何通过这个模式使用字节流的能力的,首先确定角色:字符流的子类Target,字节流子类Adaptee,适配器OutputStreamWriter InputStreamReader,具体是怎么实现的能,举个write能力的例子

字符流:

public abstract class Writer{

abstract public void write(char cbuf[], intoff, int len);

}

适配器:

public class OutputStreamWriter extendsWriter {

private final StreamEncoder se;

public void write(char cbuf[], int off, intlen) throws IOException {

       se.write(cbuf, off, len);

    }

}

和简单经典的适配器例子的区别在于StreamEncoder并不是直接的字节流子类,而是更深一层的适配器:

public class sun.nio.cs.StreamEncoder{

OutputStream out;

public void write(char cbuf[], int off, intlen)

{

最终调用了

out.write();

}

}

简单点理解,StreamEncoder包含了字节流对象,拥有了字节流的能力。所以当在客户端如此调用时:

Write wr = new OutputStreamWriter();

Wr.write();

实际上是调用了StreamEncoder中包含的字节流对象OutputStream out的write能力,当然要进行一层编码转换的包装以适应字符流的写特性。