谈谈对java I/O中装饰者模式的理解
2012-05-05 23:01
330 查看
看字面意思,装饰者就是把一个对象装饰一下,那么必要要有一个装饰着和被装饰着,被装饰者是比较原始的东西,比如一个原始的木门,大家都涂成各种颜色什么的,这里木门就是个被装饰者,各种颜料就是装饰着.装饰者要装饰被装饰者,必然要拥有一个被装饰着的对象,现在来看java I/O,I/O的本质是从文件,网络等地方读取字节流,FileInputStream是从文件中读取字节流,很原始了,它就是一个被装饰者,其他还有StringBufferInputStream,ByteArrayInputStream等,装饰着就是BufferdInputStream,猜测BufferdInputStream必然会有一个被装饰着的对象,它提供的功能是缓冲区,它可以给前面所有的被装饰者提供缓冲功能。先看headFirst设计模式一书给出的例子,比较好懂,现在假设FileInputStream已经读出字节了,要把读出来的字节中小写字母全部转化为大写字母,就是把FileInputStream装饰一下,设计一个这样的类:
很简单,一个自己的装饰者就做好了,当然你还可以有其他装饰着,如BufferdInputStream等,像下面使用:
InputStream myis = new BufferedInputStream(new LowerCaseInputStream(new FileInputStream(path)));
这样就有两个装饰着同时修饰FileInputStream了。很难理解为什么要这么用,直接用FileInputStream读出来然后再转大小写不行吗?可以这样来理解,木门为什么不直接在生产的时候就加个搞的比较好看呢?,因为木门需求还没有完全确定,每个用户需要的颜色都不一样,也就是说木门只提供最基本的功能,看FileInputStream类,它也只提供最基本的功能,如读写字节什么的,但是至于什么缓冲功能,大小写转换就需要等程序员想用的时候自己来选择,在java I/O中,FileInputStream和BufferedInputStream都继承InputStream,我的理解是:会有很多装饰者和很多被装饰者,但是装饰者要持有被装饰者的对象,假设FileInputStream等被装饰者都继承了InputStream了,这样只要传入一个InputStream进去装饰着BufferedInputStream,它就能持有所有被装饰的对象了,那么BufferedInputStream为什么还有继承InputStream呢?因为像这样的代码:
new LowerCaseInputStream(new FileInputStream(path),把被装饰者装饰了之后返回的对象是什么呢?必要还要返回被装饰者的对象,你不能把门涂层颜色就不是门了吧?所以装饰着也继承于InputStream,但是它不是直接继承InputStream,而是继承FilterInputStream,但是FilterInputStream继承InputStream,有一层FilterInputStream间接来继承InputStream,而继承与FilterInputStream的所有子类都是装饰者类,在FilterInputStream中持有一个被装饰者类的对象,这样子类就不用持有了被装饰者对象了,都从父类FilterInputStream继承过来了。最后看一下java I/O的BufferedInputStream源代码:
其实它跟LowerCaseInputStream是一样的,构造函数接受一个InputStream的被装饰者,read函数是具体的装饰功能。最后上个java I/O的包图结构
java.io.InputStream (implements java.io.Closeable)
java.io.ByteArrayInputStream
java.io.FileInputStream
java.io.FilterInputStream
java.io.BufferedInputStream
java.io.DataInputStream (implements java.io.DataInput)
java.io.LineNumberInputStream
java.io.PushbackInputStream
java.io.ObjectInputStream (implements java.io.ObjectInput, java.io.ObjectStreamConstants)
java.io.PipedInputStream
java.io.SequenceInputStream
java.io.StringBufferInputStream
从中可以看出FilterInputStream是跟其他的FileInputStream等平行的,都是继承InputStream,FilterInputStream的子类都是装饰者类。
public class LowerCaseInputStream extends FilterInputStream { protected LowerCaseInputStream(InputStream in) { super(in);//调用父类FilterInputStream,父类中持有一个被装饰者InputStream的对象 } @Override public int read() throws IOException { int c = super.read(); return (c == -1)?c:Character.toLowerCase((char)c); } }看LowerCaseInputStream,read方法相当于真正的装饰方法,要实现小写转大写的,如果传入一个FileInputStream,就持有了被装饰者对象,可以肆意的装饰它了,看怎么使用的:
String path = new String(System.getProperty("user.dir")+File.separator+"file/test.txt"); try { InputStream is = new FileInputStream(path);//没有使用装饰者的时候 int c; while((c=is.read())>0){ System.out.print((char)c); } System.out.println(); System.out.println("使用装饰者模式输出:"); InputStream myis = new LowerCaseInputStream(new FileInputStream(path)); while((c=myis.read())>0){ System.out.print((char)c); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }输出:
bCd 使用装饰者模式: bcd
很简单,一个自己的装饰者就做好了,当然你还可以有其他装饰着,如BufferdInputStream等,像下面使用:
InputStream myis = new BufferedInputStream(new LowerCaseInputStream(new FileInputStream(path)));
这样就有两个装饰着同时修饰FileInputStream了。很难理解为什么要这么用,直接用FileInputStream读出来然后再转大小写不行吗?可以这样来理解,木门为什么不直接在生产的时候就加个搞的比较好看呢?,因为木门需求还没有完全确定,每个用户需要的颜色都不一样,也就是说木门只提供最基本的功能,看FileInputStream类,它也只提供最基本的功能,如读写字节什么的,但是至于什么缓冲功能,大小写转换就需要等程序员想用的时候自己来选择,在java I/O中,FileInputStream和BufferedInputStream都继承InputStream,我的理解是:会有很多装饰者和很多被装饰者,但是装饰者要持有被装饰者的对象,假设FileInputStream等被装饰者都继承了InputStream了,这样只要传入一个InputStream进去装饰着BufferedInputStream,它就能持有所有被装饰的对象了,那么BufferedInputStream为什么还有继承InputStream呢?因为像这样的代码:
new LowerCaseInputStream(new FileInputStream(path),把被装饰者装饰了之后返回的对象是什么呢?必要还要返回被装饰者的对象,你不能把门涂层颜色就不是门了吧?所以装饰着也继承于InputStream,但是它不是直接继承InputStream,而是继承FilterInputStream,但是FilterInputStream继承InputStream,有一层FilterInputStream间接来继承InputStream,而继承与FilterInputStream的所有子类都是装饰者类,在FilterInputStream中持有一个被装饰者类的对象,这样子类就不用持有了被装饰者对象了,都从父类FilterInputStream继承过来了。最后看一下java I/O的BufferedInputStream源代码:
public BufferedInputStream(InputStream in) { this(in, defaultBufferSize); } public synchronized int read() throws IOException { if (pos >= count) { fill();//这里面会调用被装饰者的read方法 if (pos >= count) return -1; } return getBufIfOpen()[pos++] & 0xff; }
其实它跟LowerCaseInputStream是一样的,构造函数接受一个InputStream的被装饰者,read函数是具体的装饰功能。最后上个java I/O的包图结构
java.io.InputStream (implements java.io.Closeable)
java.io.ByteArrayInputStream
java.io.FileInputStream
java.io.FilterInputStream
java.io.BufferedInputStream
java.io.DataInputStream (implements java.io.DataInput)
java.io.LineNumberInputStream
java.io.PushbackInputStream
java.io.ObjectInputStream (implements java.io.ObjectInput, java.io.ObjectStreamConstants)
java.io.PipedInputStream
java.io.SequenceInputStream
java.io.StringBufferInputStream
从中可以看出FilterInputStream是跟其他的FileInputStream等平行的,都是继承InputStream,FilterInputStream的子类都是装饰者类。
相关文章推荐
- 从装饰者模式的理解说JAVA的IO包
- 透过分片定量压缩,理解Java数据流的装饰者模式
- 从装饰者模式的理解说JAVA的IO包
- 透过分片定量压缩,理解Java数据流的装饰者模式
- 由装饰者模式来深入理解Java I/O整体框架
- java装饰者模式理解
- 一张图让你理解java的装饰者模式
- JAVA装饰者模式(从现实生活角度理解代码原理)
- Java 简简单单理解观察者模式
- 谈谈我对java的理解<一>
- 深入理解Java4:Singleton单例模式七种方式
- java中装饰者设计模式
- java设计模式之装饰者模式Decorator
- Java IO 装饰者模式
- Java设计模式透析--装饰者模式(二)
- java 23种设计模式 深入理解
- Java 设计模式—装饰者模式
- 自已理解的装饰者模式
- JAVA设计模式六大原则个人理解【上】