选择jdk中的设计模式之装饰模式


概念

定义:装饰器模式动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案(具有动态性,因为继承是继承指定类,在编译时就确定了。而组合可以动态的选择拓展哪个类)

应用场景

就是在一个类的外面包了一层。具体点,就是在调用一个类的方法之前或之后,添加功能。

我们看一下《headFirst 设计模式》中的 星巴兹的例子:
在这里插入图片描述
看见没有,Mocha、Milk中有一个实例变量Beverage

  • 为什么需要继承CondimentDecorator
    就是为了让getDescription()变成一个抽象方法,好强制让具体的装饰器类实现。其实这个类不需要也行,这就继承自Beverage
  • 为什么需要继承Beverage类呢?
    是为了获取行为(如cost行为),而不是为了获取实例变量。

下面是截自《HeadFirst设计模式》中的图,表示一杯添加得有Mocha和Whip调料的BarkRoast。

注意:Whip调料类、BarkRoast基本饮料类我没添加到上面类图中。

在这里插入图片描述

jdk源码中装饰模式的应用

jdk源码中用到装饰模式的地方:java I/O
下面是类图:
在这里插入图片描述

InputStream抽象类:

 /* This abstract class is the superclass of all classes representing
 * an input stream of bytes.
 */
 abstract class InputStream implements Closeable {
   

    // MAX_SKIP_BUFFER_SIZE is used to determine the maximum buffer size to
    // use when skipping.
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;

    /**
     * Reads the next byte of data from the input stream. 
     */
    public abstract int read() throws IOException;

    /**
     * Reads some number of bytes from the input stream and stores them into
     * the buffer array .
     * */
    public int read(byte b[]) throws IOException {
   
        return read(b, 0, b.length);
    }

    /**
     * Reads up to <code>len</code> bytes of data from the input stream into
     * an array of bytes. 
     */
    public int read(byte b[], int off, int len) throws IOException {
   
	//do stuff
    }

    /**
     * Skips over and discards <code>n</code> bytes of data from this input
     * stream.
     */
    public long skip(long n) throws IOException {
   
    	//do stuff
    }

    /**
     * Returns an estimate of the number of bytes that can be read (or
     * skipped over) from this input stream without blocking by the next
     * invocation of a method for this input stream. 
   */
    public int available() throws IOException {
   
        return 0;
    }

    /**
     * Closes this input stream and releases any system resources associated
     * with the stream.
     */
    public void close() throws IOException {
   }

    /**
     * Marks the current position in this input stream. 
     */
    public synchronized void mark(int readlimit) {
   }

    /**
     * Repositions this stream to the position at the time the
     * <code>mark</code> method was last called on this input stream.
    */
    public synchronized void reset() throws IOException {
   
        throw new IOException("mark/reset not supported");
    }

    /**
     * Tests if this input stream supports the <code>mark</code> and
     * <code>reset</code> methods. 
     */
    public boolean markSupported() {
   
        return false;
    }

}

然后是FilterInputStream.java


FilterInputStream extends InputStream {
   
    /**
     * 由于每个具体的装饰器类都需要传入一个被装饰类的抽象类,所以直接提到这里。
     */
    protected volatile InputStream in;

    /**
    *由于每个具体的装饰器类的构造函数都需要传入一个InputStream,所以直接将这段提出到这里
    */
    protected FilterInputStream(InputStream in) {
   
        this.in = in;
    }
 
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值