美文网首页
JavaScript 设计模式(中)——12. 装饰者模式

JavaScript 设计模式(中)——12. 装饰者模式

作者: Haleng | 来源:发表于2019-12-22 17:59 被阅读0次

12 装饰者模式

装饰者模式定义为给对象动态地增加职责的方式;装饰者模式能够在不改变对象自身的基础上,在程序运行期间给对象动态地添加职责;

12.1 装饰函数

在 JavaScript 中可以很方便地给某个对象扩展属性和方法,但却很难在不改动某个函数源代码的情况下,给该函数添加一些额外的功能通过保存原引用的方式就可以改写某个函数,如下:

window.onload = function(){ alert (1); }
var _onload = window.onload || function(){};
window.onload = function(){
  _onload();
  alert (2);
}

这样的代码符合开放-封闭原则的,在增加新功能的时候,确实没有修改原来的 window.onload 代码,但是这种方式存在以下两个问题:

  • 必须维护 _onload 这个中间变量,如果函数的装饰链较长,或者需要装饰的函数变多,这些中间变量的数量也会越来越多;
  • 其实还遇到了 this 被劫持的问题,遇到该问题时需要 用Function.prototype.apply() 手动设置 this 指向,如下document.getElementById 方法;
<html>
  <button id="button"></button>
  <script>
    var _getElementById = document.getElementById;
    document.getElementById = function(){
      alert (1);
      return _getElementById.apply( document, arguments );
    }
    var button = document.getElementById( 'button' );
  </script>
</html>

12.2 用 AOP (面向切面编程)装饰函数

  1. Function.prototype.before 方法和Function.prototype.after 方法实现:
Function.prototype.before = function( beforefn ){
  var __self = this; // 保存原函数的引用
  return function(){ // 返回包含了原函数和新函数的"代理"函数
    beforefn.apply( this, arguments ); // 执行新函数,且保证 this 不被劫持,新函数接受的参数
    // 也会被原封不动地传入原函数,新函数在原函数之前执行
    return __self.apply( this, arguments ); // 执行原函数并返回原函数的执行结果,
    // 并且保证 this 不被劫持
  }
}
Function.prototype.after = function( afterfn ){
  var __self = this;
  return function(){
    var ret = __self.apply( this, arguments );
    afterfn.apply( this, arguments );
    return ret;
  }
};

2.用 AOP 装饰函数修改上面例子:

<html>
  <button id="button"></button>
  <script>
  Function.prototype.before = function( beforefn ){
    var __self = this;
    return function(){
      beforefn.apply( this, arguments );
      return __self.apply( this, arguments );
    }
  }
  document.getElementById = document.getElementById.before(function(){ alert (1); });
  var button = document.getElementById( 'button' );
  console.log( button );
  </script>
</html>

12.3 AOP 的应用实例

12.4 装饰者模式和代理模式

代理模式和装饰者模式最重要的区别在于它们的意图和设计目的。

  • 代理模式:当直接访问本体不方便或者不符合需要时,为这个本体提供一个替代者,本体定义了关键功能,而代理提供或拒绝对它的访问,或者在访问本体之前做一些额外的事情;代理模式强调一种关系( Proxy 与它的实体之间的关系),这种关系可以静态的表达,在一开始就可以被确定;
  • 装饰者模式:为对象动态加入行为;装饰者模式用于一开始不能确定对象的全部功能时;代理模式通常只有一层代理-本体的引用,而装饰者模式经常会形成一条长长的装饰链;

12.5 装饰者模式小结

装饰函数是 JavaScript 中独特的装饰者模式,这种模式在实际开发中非常有用;同时在框架开发中也十分有用,通过装饰者模式为框架里的函数提供的一些稳定而方便移植的功能,这些个性化的功能可以在框架之外动态装饰上去,这样能避免为了让框架拥有更多的功能,而去使用一些 if、 else 语句预测用户的实际需要;

系列链接

  1. JavaScript 设计模式(上)——基础知识
  2. JavaScript 设计模式(中)——1.单例模式
  3. JavaScript 设计模式(中)——2.策略模式
  4. JavaScript 设计模式(中)——3.代理模式
  5. JavaScript 设计模式(中)——4.迭代器模式
  6. JavaScript 设计模式(中)——5.发布订阅模式
  7. JavaScript 设计模式(中)——6.命令模式
  8. JavaScript 设计模式(中)——7.组合模式
  9. JavaScript 设计模式(中)——8.模板方法模式
  10. JavaScript 设计模式(中)——9.享元模式
  11. JavaScript 设计模式(中)——10.职责链模式
  12. JavaScript 设计模式(中)——11. 中介者模式
  13. JavaScript 设计模式(中)——12. 装饰者模式
  14. JavaScript 设计模式(中)——13.状态模式
  15. JavaScript 设计模式(中)——14.适配器模式
  16. JavaScript 设计模式(下)——设计原则
  17. JavaScript 设计模式练习代码

本文主要参考了《JavaScript设计模式和开发实践》一书

相关文章

  • JavaScript 设计模式(中)——12. 装饰者模式

    12 装饰者模式 装饰者模式定义为给对象动态地增加职责的方式;装饰者模式能够在不改变对象自身的基础上,在程序运行期...

  • JavaScript 设计模式核⼼原理与应⽤实践 之 结构型设计

    JavaScript 设计模式核⼼原理与应⽤实践 之 结构型设计模式 装饰器模式,又名装饰者模式。它的定义是“在不...

  • 装饰者模式

    JavaScript 设计模式 张容铭第十二章 房子装修--装饰者模式 (102页) 装饰者模式(Decorato...

  • javascript设计模式——装饰者模式

    装饰者模式:在不改变原对象的基础上,通过对其进行包装扩展,使原有对象可以满足用户的更复杂需求 需求:对表单输入框进...

  • 装饰者模式【javascript设计模式】

    其实生命就是这样,从无到有,从稚嫩到成熟。现状态转变自前一个状态,只是多了点东西,它们就变得相互独立,形同陌路。 ...

  • 设计模式

    设计模式 单例模式、装饰者模式、

  • 装饰者设计模式-RecyclerView添加头部和底部

    引言 装饰者设计模式,装饰者设计模式在Android系统源码中也能经常见到,如IO流、ContextWrapper...

  • 组合模式设计

    一、设计模式 javascript里面给我们提供了很多种设计模式: 工厂、桥、组合、门面、适配器、装饰者、享元、代...

  • 装饰者模式设计

    一、设计模式 javascript里面给我们提供了很多种设计模式: 工厂、桥、组合、门面、适配器、装饰者、享元、代...

  • 适配器模式

    一、设计模式 javascript里面给我们提供了很多种设计模式: 工厂、桥、组合、门面、适配器、装饰者、享元、代...

网友评论

      本文标题:JavaScript 设计模式(中)——12. 装饰者模式

      本文链接:https://www.haomeiwen.com/subject/cyfnnctx.html