装饰者模式的应用——InputStream

前言

​ 在之前的博客——《装饰者模式(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();
        }
      // 小插曲结束
    }
}

运行结果

这里写图片描述

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值