设计模式:装饰模式

我们经常会遇见,一些不想改变接口,希望在接口上边“加强”,像是给个装饰品一样,在接口方法名字和参数都不变的情况下添加新的增强的部分。这就涉及到一个装饰模式。

常见的装饰模式以及用途

哪里装饰模式体现的做突出,那一定是Java的IO类。因为涉及到太多的实现和子类,如果单纯的通过继承,估计各个子类里面的代码估计要爆炸了。

比如下面这个读取文件流的代码:
FileInputStream 是专门用来读取文件流的子类。BufferedInputStream 是一个支持带缓存功能的数据读取类,可以提高数据读取的效率

InputStream in = new FileInputStream("/user/zhangpeng/zp.txt");
InputStream bin = new BufferedInputStream(in);
byte[] data = new byte[128];
while (bin.read(data) != -1) {
  //...
}

看一下InputStream

package java.io;

public abstract class InputStream implements Closeable {
    private static final int MAX_SKIP_BUFFER_SIZE = 2048;

    public InputStream() {
    }

    public abstract int read() throws IOException;

    public int read(byte[] var1) throws IOException {
        return this.read(var1, 0, var1.length);
    }

在这里插入图片描述
FilterInputStream

public
class FilterInputStream extends InputStream {

BufferedInputStream

public
class BufferedInputStream extends FilterInputStream {

    private static int DEFAULT_BUFFER_SIZE = 8192;

    /**
     * The maximum size of array to allocate.
     * Some VMs reserve some header words in an array.
     * Attempts to allocate larger arrays may result in
     * OutOfMemoryError: Requested array size exceeds VM limit
     */
    private static int MAX_BUFFER_SIZE = Integer.MAX_VALUE - 8;

    /**
     * The internal buffer array where the data is stored. When necessary,
     * it may be replaced by another array of
     * a different size.
     */
    protected volatile byte buf[];

装饰模式的构成以及和代理模式的区别

说句实在话,看组成部分,实际上装饰模式和代理模式差不多,都是四个部分。

抽象构件(Component)角色:给出一个抽象接口,已规范准备接收附加责任的对象。
具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类
装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。

这里是:
git装饰器模式代码

以下是结构图:
在这里插入图片描述
其实对比代理模式你会发现和装饰器模式很像,我们稍微改一改我们的代理模式的继承关系,基本代码结构上装饰器一样。

一样的结构取两个名字,实际上这俩模式适用的场景有关,以下是别人的一个阐述关于二者之间

代理模式体现封装性,非业务功能与业务功能分开,而且使用是透明的,使用者只需要关注于自身的业务,在业务场景上适用于对某一类功能进行加强,比如日志,事务,权限。
装饰器模式体现多态性,优点在于避免了继承爆炸,适用于扩展多个平行功能。在场景上,这些扩展的功能可以像火车厢一样串起来,使原有的业务功能不断增强。

都是对某个功能加强,一个是为了封装,不同的业务分隔开,一个是多样性为了各种各样的花样实现(解决只依靠继承这种,一旦多起来问题,就代码很爆炸的这种)

装饰模式与适配器模式:

装饰模式与适配器模式有的地方会合在一起,叫做“包装模式”,但是实际二者互为逆操作。一个是我接口不变的条件下直接增强功能,比如说以前问你擅长什么,你只会“唱跳rap”,现在增强一下你还会“打篮球”。

适配器模式则是改变接口不改变功能,比如说有个老的类现在不要用了,要用新的来替代,但是第三方用的还是老的类的方法,解决方式就是改写老的类的方法,去兼容新的类的方法来实现,这样第三方无感知,也不需要去做替换兼容。

半透明这个也好理解,就是你继承了另一个类,但是你有你自己的方法,这些事你父类没有的,某种意义上这个接口是你自己独有的,你又是装饰模式,但是由于这个独有的,你和父类不一致,不算完全“透明”,所以叫半透明。
在这里插入图片描述
举个例子PushbackInputStream,他继承了FilterInputStream ,但是他有自己unread(),打破了非常理论理想化的装饰器模式(接口不变,功能增强)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值