装饰者模式 Decorator Pattern

父博文地址:设计模式 - Design Patterns


一、是什么

  1. 问题

    使用继承是静态的扩展:

    • 随着系统功能增多造成了类数量指数级增加。
    • 且基类的功能并不适用于所有子类。
  2. 寻找一个设计模式原则

    开闭原则:类应该对扩展开放,对修改关闭。换句话说:在不修改类的前提下扩展类。

  3. 装饰者模式定义

    动态的将责任附加到对象 上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

    类图如下:

    这里写图片描述

二、问答

  1. AbstractDecorator 及其子类依然继承自AbstractComponent 不是吗?

    我们依然使用了继承,的确如此。不过这么做的重点在于,装饰者和被装饰者需要是同一个类型,这很关键。我们只是利用继承达到“类型匹配”,而不是利用继承获取“行为”。

  2. 加入行为

    我们不是通过继承来“加入新行为”,而是通过“组合”。

  3. 为什么装饰者是抽象类?

    通常使用抽象类,当然Java 中也可以使用接口,此时需要把构造函数定义在各个装饰者子类中。

三、实例

1. FilterInputStreamInputStream 的装饰器

类图如下:

这里写图片描述

  1. 介绍

    InputStream 是抽象被装饰类,ObjectInputStream, FileInputStream, ByteArrayInputStream等是可以被装饰的具体组件。

    FilterInputStream 是装饰者类(这里没有设计为抽象),BufferedInputStream, LineNumberInputSream, DataInputSream等是具体的装饰者类。

  2. FilterInputStream 代码

    public class FilterInputStream extends InputStream {
    
        protected volatile InputStream in;
    
        protected FilterInputStream(InputStream in) {
            this.in = in;
        }
    
        public int read() throws IOException {
            return in.read();
        }
    
        // others
    }

    可以看到,包装类只有一个有参数的构造函数,参数是被包装类。包装类可以动态的添加功能,这里覆盖了read()并简单的调用被包装类的同名方法。

  3. 一个可能的用例

    这里写图片描述

    FileInputSreamBufferedInputSream装饰,BufferedInputSream又被LineNumberInputSream装饰。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值