设计模式之装饰者模式

2019-06-17  本文已影响0人  回调的幸福时光

一、基础介绍

在不改变原对象的基础上,给对象动态增加职责(功能:属性或方法)的方式称为装饰者模式。

装饰者模式 UML 类图

二、装饰函数

2.1 通过保存原引用的方式

如果需要绑定 onload 事件,但又不确定是否别人已经绑定过,为了避免覆盖掉之前的 window.onload 函数中的行为,常见的做法是:

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

window.onload = function() {
  _onload();
  // do otherthing
}

缺点:

2.2 用 AOP 装饰函数
Function.prototype.before = function (beforefn) {
  var _self = this; // 保存原函数的引用
  return function () {
    beforefn.apply(this, arguments); // 执行新函数,且保证 this 不被劫持
    _self.apply(this, arguments);
  }
}

Function.prototype.after = function(afterfn) {
  var _self = this;
  return function () {
    var ret = _self.apply(this, arguments);
    afterfn.apply(this, arguments);
    return ret;
  }
}

如果不喜欢上面污染原型的方式,可采用下面的方式:

function before(fn, beforefn) {
  return function () {
    beforefn.apply(this, arguments);
    return fn.apply(this, arguments);
  }
}

function after(fn, afterfn) {
  return function () {
    var ret = fn.apply(this, arguments);
    afterfn.apply(this, arguments);
    return ret;
  }
}
2.3 ES7 Decorator

推荐阅读 阮一峰: 装饰器

三、装饰者模式和代理模式的区别

相同点:

不同点:
代理模式的目的:当直接访问本体不方便或者不符合需要时,为本体提供一个替代者,控制对本体的访问。
代理模式强调 Proxy 与它的实体之间的关系。
代理模式通常只有一层代理-本体的引用。

装饰者模式的目的:为对象动态加入行为。
装饰者模式经常会形成一条长长的装饰链。

装饰者模式和适配器模式的区别

相同点: 不改变原有接口。

适配器的目的在于解决两个接口不兼容。

参考

《JavaScript 设计模式与开发实践》曾探
《JavaScript 设计模式》张容铭
Javascript设计模式系统讲解与应用

上一篇 下一篇

猜你喜欢

热点阅读