Java IO 中的装饰者(Decorator)模式(一)

   一直对java.io一知半解,每到用时便google下例子代码----拿来主义,已是我之痼疾。
   这几日便得了闲,拿了JDK 5的Doc、Thinking In Java(4th)和大话设计模式, 对照着JDK 5的源代码
开始看,翻来覆去几回,稍稍有了点眉目,便就上来得瑟一回,记个笔记。

--------------------------------------------------------------------------------------------
一. 从InputStream 及其子类的结构入手

   java.io中类数众多,名称相似,一眼看去,已是花了,至于哪些是输入相关的基本类,哪些又是装饰者类
就分不清了。所以我们就先来理一理其中的结构:

   java.io中的类大致分为两个部分:
    1. InputStream、OutputStream --- 是对字节序列进行操作的抽象类,由JDK1.0发布。
    2. Reader、Writer            --- 是基于Unicode Code Unit 进行操作的抽象类, 由JDK1.1发布。

   我们今天先从InputStream入手,参考JDK文档画出了它的UML 类图(请从附件下载,图的篇幅较宽,就不贴了)
  
  图解 ---参考附件中图的左边部分(InputStream),右边是Reader:

    1. 输入相关的抽象超类:java.io.InputStream

    2. 输入相关的基本类:继承自java.io.InputStream,具体使用方法请参考JDK文档,但大致可以从其名字中看出其含义。总共有8个:
         
 
                   ByteArrayInputStream
                   PipedInputStream
                   SequenceInputStream
                   FileInputStream
                   ObjectInputStream
                   StringBufferInputStream(已经过时,由StringReader代替)
                   javax.sound.sampled.AudioInputStream(外部类)
                   org.omg.CORBA.portable.InputStream(外部类)


    3. 装饰者超类:FilterInputStream,同样也继承自java.io.InputStream

    4. 装饰者子类:继承自FilterInputStream,用于装饰上面的 "2. 输入相关的基本类",共有4个:
 
                   BufferedInputStream
                   PushbackInputStream
                   DataInputStream
                   LineNumberInputStream(已经过时)


二. InputStream 和 装饰者模式

   众人皆知java的输入输出包"java.io"是一个装饰者模式的典型案例,这从下面这个代码就可以大致看出:

  
final BufferInputStream bin =
 new BufferInputStream(new FileInputStream("C:\\test.log"));


   但具体是怎样子的还是需要查看JDK源代码:

1.  java.io.InputStream  == 装饰者模式中的所有类(装饰者和被装饰者)的抽象超类
public abstract class InputStream implements Closeable {
     // 定义抽象方法:read
     public abstract int read() throws IOException;
}



   2.java.io.FileInputStream == 具体的被装饰者对象
public class FileInputStream extends InputStream {
    public FileInputStream(String name) throws FileNotFoundException {
        this(name != null ? new File(name) : null);
    }
    // 调用本地read方法
    public native int read() throws IOException;
}


   3.java.io.FilterInputStream == 装饰者对象的超类
  
public class FilterInputStream extends InputStream {
    /**
     * The input stream to be filtered. 
     */
    protected volatile InputStream in;

    protected FilterInputStream(InputStream in) {
	this.in = in;
    }
   
    // 装饰者超类的read方法
    public int read() throws IOException {
	return in.read();
    }
}

   


    4.java.io.BufferedInputStream == 具体的装饰者对象
public class BufferedInputStream extends FilterInputStream {

    public BufferedInputStream(InputStream in) {
	this(in, defaultBufferSize);
    }

    public BufferedInputStream(InputStream in, int size) {
	super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
	buf = new byte[size];
    }

    // 具体装饰者类的read方法
    public synchronized int read() throws IOException {
	if (pos >= count) {
	    fill();
	    if (pos >= count)
		return -1;
	}
	return getBufIfOpen()[pos++] & 0xff;
    }
}


   有过模式设计经验的同学不难发现这是一个经典的装饰者模式。

   下一次,我们来看看InputStream和Reader的关系。

  

  

你可能感兴趣的:(java,设计模式,jdk,Google,UML)