现在的位置: 首页 > 综合 > 正文

java.io的Decorator设计模式

2013年08月31日 ⁄ 综合 ⁄ 共 3588字 ⁄ 字号 评论关闭

当提到Decorator(装饰者)模式的时候,都经常会提到java.io的设计模式。

作为一个灵活的,可扩展的类库,JDK中使用了大量的设计模式,对JDK中模式的研究不仅能增加对模式的理解,而且还有利于更透彻的了解类库的结构和组成。

在java.io包中,OutputStream,InputStream,Reader,Writer等都用到了Decorator模式。

Decorator模式简介:

Decorator模式又称Wrapper(包装器)模式,它用于给一个对象动态的添加一些额外的职责。

     以下是Decorator模式的UML示意图。image

Component:被装饰对象的基类

定义对象的接口/抽象类,可以给这些对象动态增加职责

ConcreteComponent:具体被装饰的对象

定义具体的对象,Decorete可以为它增加额外的职责

Decorator:装饰者抽象类

维护一个指向Component实例的引用,并且定义了与Component一致的接口

ConcreteDecorator:具体装饰者

具体的装饰对象,给内部持有的具体被装饰对象增加具体的职责

java.io包中OutputStream中的Decorator模式:

在java.io包中OutputStream是一个的Decorator模式的设计,OutputStream抽象类作为Decorator,BufferedOutputStream是ConcreteDecorator。

他们的关系如下图的UML图中示意:

image

其中OutputStream作为Component和Decorator,FilterOutputStream和BufferedOutputStream作为ConcreteDecorator。其中BufferedOutputStream也对FilterOutputStream做了具体的装饰,如flush()和write(int)方法。

OutputStream是一个抽象类,它是所有输出流的公共父类,其源代码如下:

package java.io;

public abstract class OutputStream implements Closeable, Flushable {

    public abstract void write(int b) throws IOException;

    public void write(byte b[]) throws IOException {

    write(b, 0, b.length);

    }

    public void write(byte b[], int off, int len) throws IOException {

    if (b == null) {

        throw new NullPointerException();

    } else if ((off < 0) || (off > b.length) || (len < 0) ||

           ((off + len) > b.length) || ((off + len) < 0)) {

        throw new IndexOutOfBoundsException();

    } else if (len == 0) {

        return;

    }

    for (int i = 0 ; i < len ; i++) {

        write(b[off + i]);

    }

    }

    public void flush() throws IOException {

    }

    public void close() throws IOException {

    }

}

它定义了write(int b)的抽象方法。这相当于Decorator模式中的Component类。
FilterOutputStream是从OutputStream中继承的。

package java.io;

public  class FilterOutputStream extends OutputStream {

    protected OutputStream out;

    public FilterOutputStream(OutputStream out) {

    this.out = out;

    }

    public void write(int b) throws IOException {

    out.write(b);

    }

    public void write(byte b[]) throws IOException {

    write(b, 0, b.length);

    }

    public void write(byte b[], int off, int len) throws IOException {

    if ((off | len | (b.length - (len + off)) | (off + len)) < 0)

        throw new IndexOutOfBoundsException();

    for (int i = 0 ; i < len ; i++) {

        write(b[off + i]);

    }

    }

    public void flush() throws IOException {

    out.flush();

    }

    public void close() throws IOException {

    try {

      flush();

    } catch (IOException ignored) {

    }

    out.close();

    }

}

FilterOutputStream中的protected OutputStream
out;属性相当于Decorator的Component。FilterOutputStream中并未真正给出write(int)的实现,而是调用out的write方法,flush()方法也同样。具体的write(int)方法和flush()方法是在BufferedOutputStream中实现的。

BufferedOutputStream的代码实现如下:

package java.io;

public

class BufferedOutputStream extends FilterOutputStream {

    protected byte buf[];

    protected int count;

    public BufferedOutputStream(OutputStream out) {

    this(out, 8192);

    }

    public BufferedOutputStream(OutputStream out, int size) {

    super(out);

        if (size <= 0) {

            throw new IllegalArgumentException("Buffer size <= 0");

        }

    buf = new byte[size];

    }

    /** Flush the internal buffer */

    private void flushBuffer() throws IOException {

        if (count > 0) {

        out.write(buf, 0, count);

        count = 0;

        }

    }

    public synchronized void write(int b) throws IOException {

    if (count >= buf.length) {

        flushBuffer();

    }

    buf[count++] = (byte)b;

    }

    public synchronized void write(byte b[], int off, int len) throws
IOException {

    if (len >= buf.length) {

        flushBuffer();

        out.write(b, off, len);

        return;

    }

    if (len > buf.length - count) {

        flushBuffer();

    }

    System.arraycopy(b, off, buf, count, len);

    count += len;

    }

    public synchronized void flush() throws IOException {

        flushBuffer();

    out.flush();

    }

}

在BufferedOutputStream类中给出了flush()和write(int)的具体实现,是Decorator的具体装饰。

参考资料:

软件包
java.io 的分层结构

Original
GoF Patterns

来杯咖啡-装饰者模式(Decorator)

JAVA IO 设计模式彻底分析

 

抱歉!评论已关闭.