寻找jdk中的设计模式之适配器模式

版权声明:转载请标明出处 https://blog.csdn.net/wobushixiaobailian/article/details/87855213


概念

适配器模式:就是将一个接口转换为另一个接口。适配器模式是将用户接口绑定在一起,而不是将用户实现绑定在一起。

应用场景

应用场景正如概念所说,当你需要将一个接口转换(由于某种原因,或者单纯是你想这样做)为另一个接口时使用。

JDK中的应用

在jdk中的应用之一InputStreamReader、OutputStreamWriter。第一个类是将byte流转化为char流,而第二个类刚好相反。

具体使用例子:

 public static void main(String[] args) throws FileNotFoundException {
        /*从/home/a.txt文件读入数据*/
        Reader reader= null;
        try {
            reader = new InputStreamReader(new FileInputStream("/home/a.txt"));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        //写入数据到控制台
        Writer writer= new OutputStreamWriter(System.out);
        //缓存
        char[] buff=new char[18];
        /*从a.txt文件读入数据到缓存中*/
        try {
            reader.read(buff);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /*从缓存中读出数据*/
        try {
            writer.write(buff);
        } catch (IOException e) {
            e.printStackTrace();
        }

        /*冲出输出流中的数据*/
        try {
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

a.txt

我不是小白脸,little feng

运行结果:

我不是小白脸,little feng

注意,我用的是ubuntu18.04,如果用的是Windows系统,把new FileInputStream("/home/a.txt")改为相应的路径就行了。

下面是我对InputStreamReader的思考

思考:
InputStreamReader里面有一个StreamDecoder实例对象sd,除了构造函数以外,其他方法都是简单的调用sd相应的方法, 一点儿处理都没得,那为什么还用用适配器模式呢?还不如直接使用StreamDecoder类算了。看了一下源码,我注意到StreamDecoder的构造方法的访问属性都是default的,在有些地方是不能直接通过new来创建对象,然而可以通过forInputStreamReader来创建,看来这不是原因所在*/

下面是InputStreamReader的源码:

public class InputStreamReader extends Reader {

    private final StreamDecoder sd;


    public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }


    public InputStreamReader(InputStream in, String charsetName)
        throws UnsupportedEncodingException
    {
        super(in);
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        sd = StreamDecoder.forInputStreamReader(in, this, charsetName);
    }


    public InputStreamReader(InputStream in, Charset cs) {
        super(in);
        if (cs == null)
            throw new NullPointerException("charset");
        sd = StreamDecoder.forInputStreamReader(in, this, cs);
    }


    public InputStreamReader(InputStream in, CharsetDecoder dec) {
        super(in);
        if (dec == null)
            throw new NullPointerException("charset decoder");
        sd = StreamDecoder.forInputStreamReader(in, this, dec);
    }


    public String getEncoding() {
    	//this
        return sd.getEncoding();
    }


    public int read() throws IOException {
    	//this
        return sd.read();
    }


    public int read(char cbuf[], int offset, int length) throws IOException {
        //this
        return sd.read(cbuf, offset, length);
    }


    public boolean ready() throws IOException {
    	//this
        return sd.ready();
    }

    public void close() throws IOException {
    	//this
        sd.close();
    }
}

下面是我在main函数里面,纯用StreamDecoder实现上面输出数据到控制台的代码

 public static void main(String[] args) throws FileNotFoundException {
              try {
            StreamDecoder sd=StreamDecoder.forInputStreamReader(new FileInputStream("/home/a.txt"), new Object(), (String)null);
            char[] buff2=new char[18];
            try {
                //读入数据到buff2中
                sd.read(buff2,0,buff2.length);
                System.out.println(buff2);
            } catch (IOException e) {
                e.printStackTrace();
            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }

so,为什么呢?

参考文献

装饰模式、适配器模式、外观模式的区别

猜你喜欢

转载自blog.csdn.net/wobushixiaobailian/article/details/87855213