装饰器模式

一、意图与动机

动态的给一个对象而不是整个类添加一些额外的职责。

二、适用性

  1. 一下情况适合使用装饰器模式
  2. 不影响其它对象职责的情况下,动态、透明的各条单个对象添加职责
  3. 当不能采用生成子类的方式进行扩充时。一种情况是,可能有大量独立的扩展,为支持没有组组则将产生大量的子类,使得子类数目呈爆炸式增长。另一种情况是因为类定义被隐藏,或者类定义不能用于生成子类。

三、结构


四、实现


  1. 使用装饰器模式需要注意以下几点
  2. 接口一致性。装饰对象的接口必须与它装饰的对象的接口是一致的,因此,结构图中,CoreFunctionality和OptionalWrapper必须有一个公共的接口。
  3. 省略抽象的Decorator类,也就是结构图中的OptionalWrapper类。当仅仅需要添加一个职责时,没有必要定义抽象的Decorator类,直接在将请求转发的职责放到具体类中
  4. 保持基础接口的简单性。为了保持接口一致性,原始类和装饰类有一个公共的接口,保持这个公共接口的简单性很重要,否则CoreFunctionality会过于庞大和复杂。
  5. 改变对象外壳与改变对象内核。可以将Decorator看着一个对象的外壳,可以改变对象的行为而不是类。如果要改变对象的内核,策略模式是一种选择

五、案例

装饰器模式在java的IO库中大量使用,现抽取部分示例如下

public class BufferedReader extends Reader {

    private Reader in;

    private char cb[];
    private int nChars, nextChar;

    private static final int INVALIDATED = -2;
    private static final int UNMARKED = -1;
    private int markedChar = UNMARKED;
    private int readAheadLimit = 0; /* Valid only when markedChar > 0 */

    /** If the next character is a line feed, skip it */
    private boolean skipLF = false;

    /** The skipLF flag when the mark was set */
    private boolean markedSkipLF = false;
    
    // ......
}

public class InputStreamReader extends Reader {

    private final StreamDecoder sd;

    /**
     * Creates an InputStreamReader that uses the default charset.
     *
     * @param  in   An InputStream
     */
    public InputStreamReader(InputStream in) {
        super(in);
        try {
            sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
            // The default encoding should always be available
            throw new Error(e);
        }
    }

    // ......
}

类似该例子,java io库中,还有很多使用装饰器模式的例子,如FilterReader、FilterWriter、BufferedWriter、PrintWriter、LineNumberReader、PushBackReader。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值