设计模式 - 装饰者模式

2019-06-13 00:00:00

当你不得不在别人的代码之上添加功能时,你该怎么做?

什么是装饰者?

定义:不改变对象自身的基础上,在运行过程中动态地给对象添加功能。

通俗点说,通常是基于一个函数,装饰之后生成另外一个函数。

装饰者最大的特点就是不改变原函数,所以它的用途主要在原函数上添加功能。

装饰者的两种用法

保存原引用的改写
window.onload = function() {
  console.log(1);
  console.log(this.a)   // 此处 this指向 window
}
var _onload = window.onload || function() {};
window.onload = function() {
  _onload();
  console.log(2);
}

该种方式看上去行,但是存在两个问题:

  • 1、存在临时变量,但装饰的方法多了之后,就非常冗余。
  • 2、当原函数里面存在 this指向时,就出错了。
AOP装饰函数

AOP(面向切面编程):主要作用是将跟业务逻辑无关的功能抽取出来,再动态掺入业务逻辑模块。与业务逻辑无关的功能通常有:日志统计、埋点、异常处理等。

当然,这只是一个思想,并不一定完全遵守抽取的是与业务逻辑无关的功能,关键在于,在函数某个部分插入某个功能,就像把面包切成好几块,然后可以在切面添加不同的佐料一般。

装饰者模式其实就是采用了 AOP思想,如下是通过原型的方式实现装饰者模式:

// 以下两种函数均为高阶函数。高阶函数的定义是,参数是函数,或者返回值是函数
Function.prototype.before = function (beforeFn) {
    let _self = this
    return function () {
        beforeFn.apply(this, arguments)
        return _self.apply(this, arguments)
    }
}

Function.prototype.after = function (afterFn) {
    let _self = this
    return function () {
        let val = _self.apply(this, arguments)
        afterFn.apply(this, arguments)
        return val
    }
}

以上装饰者模式实现了不改变原函数功能的情况下,动态添加新的功能。该模式常见适用场景:

  • 原代码复杂,不想修改原代码的同时又增加新的功能
  • 在原代码之前添加埋点、校验等功能时。

Gitalking ...

Markdown is supported

Be the first guy leaving a comment!