装饰者模式的应用——InputStream

来源:互联网 发布:服装库存软件 编辑:程序博客网 时间:2024/06/13 03:24

前言

​ 在之前的博客——《装饰者模式(Decorator Pattern)——给爱用继承的人一个全新的设计眼界》学习了装饰模式,但是也只是一知半解,连java中使用装饰者设计模式最典型的InputStream家族都没指出,似乎有点水了点。所以,在这里做一个补充。

​ 还记得如何从一个控制台读取一行字符串吗?

 BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( System.in ) );        try {            System.out.println( bufferedReader.readLine());            bufferedReader.close();        } catch (IOException e) {            e.printStackTrace();        }

​ 在java IO中,这种形式new xx(new xxx(new xxxx( new xxxxxx())))似乎很常见。事实上,他们都来继承自抽象类InputStream。下面将简单介绍一下InputStream。

类图

这里写图片描述

  1. InputStream: 这是一个抽象类,相当于装饰者模式中的超类。在这个抽象类中只有一个抽象方法read(),也就是一定要用子类去实现的。不过别的函数会调用这个方法。所以,InputStream的所有子类都必须实现read()。
  2. FileInputStream、ByteArrayInputStream、StringBufferedInputStream等:相当于装饰者模式的具体组件。实现自InputStream。
  3. FilterInputStream:抽象装饰者类。继承InputStream。
  4. BufferedInputStream、DataInputStream、CheckedInputStream等:具体的装饰类,继承自FilterInputStream。

一些实践

描述:设计一个简单类,在读文件时,将大写字母转化为小写字母,将小写字母转化为大写字母。

思路:在设计时可以通过继承抽象装饰者类(FilterInputStream)来实现一个装饰类。通过调用InputStream类或其他子类提供的一些方

法再加上逻辑判断代码从而可以很简单地实现这个功能。

小插曲:在这中间,写了一个测试类,继承FilterInputStream,输出一段中文字符。

代码实现:

package inputStreamObserver;import java.io.*;/** * <p>ClassName      ElogInputStream * <p>Description * <p>Author         ChongLou * <p>Version * <p>Date           2017/8/6 0:27 */public class ElogInputStream extends FilterInputStream {    public ElogInputStream(InputStream in) {        super( in );        System.out.println( "Elog.read()-----there will change the style of Character!" );    }    public final int read() throws IOException {//        System.out.println( "Elog.read()-----there will change the style of Character!" );        int c = 0;        if ((c = super.read()) != -1) {            if (Character.isLowerCase( c )) {                //将小写转换为大写                return Character.toUpperCase( c );            } else if (Character.isUpperCase( c )) {                //大写转化成小写                return Character.toLowerCase( c );            } else {                return c;            }        } else {            return -1;        }    }}
package inputStreamObserver;import java.io.*;/** * <p>ClassName      ClogInputStream * <p>Description * <p>Author         ChongLou * <p>Version * <p>Date           2017/8/6 0:27 */public class ClogInputStream extends FilterInputStream {    public ClogInputStream(InputStream in) {        super( in );        System.out.println( "Clog.read()----这里输出的是中文" );    }    public int read() throws IOException {        return in.read();    }}
package inputStreamObserver;import java.io.*;/** * <p>ClassName      TestInputStream * <p>Description * <p>Author         ChongLou * <p>Version * <p>Date           2017/8/6 10:24 */public class TestInputStream {    public static void main(String[] args) {        File file = new File( "E:/Desktop/test.txt" );        // 大小写互换。        int c = 0;        try {            InputStream inputStream = new ElogInputStream( new FileInputStream( file ) );            while ((c = inputStream.read()) != -1) {                System.out.print( (char) c );            }            inputStream.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        System.out.println();        //这里是小插曲,开始,请自动忽略        // 重写read,输出一段中文字符。       int num = 0;        try {            InputStream in = new ClogInputStream( new FileInputStream( file ) );            while ((num = in.read()) != -1) {                System.out.print( (char) num );            }            in.close();        } catch (Exception e) {            e.printStackTrace();        }      // 小插曲结束    }}

运行结果

这里写图片描述

原创粉丝点击