为了避免某个对象负责过多的功能,需要使用装饰者模式动态的给某个对象添加额外的职责。
因为在传统的面相对象语言中,给对象添加功能常使用继承的模式,一个对象功能过多时,继承的对象也会带上不必要的部分。
装饰者模式是在程序运行期间给对象动态添加职责。
具体的操作为,不对原对象进行改变,使用装饰者对象对原对象进行包装,使它们具备相同的接口,当装饰者对象被调用时,原对象的接口被装饰者对象酌情调用,类似于一种在原本接口后添加了一些副作用。

wrapper or decorator ?

从结构上来看,wrapper对该模式的描述更为贴切,对象对对象进行一层层包装。

问题

装饰者模式常出于避免改动原代码的目的,实操时会使用中间变量来保存原函数的引用,(比如axios的劫持器?)但也会带来一些问题。

  1. 装饰链过长时,中间的变量会线性增加;
  2. 装饰过程中this的丢失问题,这是js特有的。

    使用AOP实现装饰者模式


    Funcition.prototype.before``Function.prototype.after
    这么看来AOP封装的是将不同业务切面组合在一起的这个行为,手动把每个业务切面组合在一起的效果和使用before,after的效果是一样的。
    指正:还是有所不同的,手动把各个业务切面组合在一起的这个函数也可以是不必要的。业务切面的流程控制和组合都可以放入装饰者函数中,也就是这些步骤可以在before或after函数中进行,这样暴露在外的完全是纯净的无任何耦合的函数。

    与代理模式

    装饰 者模式和代理模式都实现了对对象的间接引用,他们最重要的区别在于使用意图和设计目的。

  3. 代理模式的目的是,当直接访问本体不方便或不符合需要时,为这个本体提供一个替代者。本体定义关键功能,代理提供或拒绝它的访问,或在访问之前做一些额外的事情。代理模式强调一种关系,这种关系可以静态的表达,也就是说,这种关系在一开始就被确定。

  4. 装饰者模式用于一开始不能确定对象的全部功能时,它对对象动态加入行为。
  5. 代理模式通常只有一层代理-本体引用,装饰者模式经常会形成一条长装饰链。