饰模式是种动态的向一个类(方法)添加行为的设计模式.它不会直接修改原类(方法).

装饰模式比生成子类更灵活,它不会影响原来的类(方法),可以增对单独的方法增加新的行为.

在面向对象的编程中,装饰器模式是一种设计模式,它允许将行为静态或动态地添加到单个对象,而不会影响同一类中其他对象的行为。装饰器模式通常用于遵守单一责任原则,因为它允许在具有独特关注区域的类之间划分功能。

例子

1
2
3
4
5
6
7
8
9
10
11
12
// 给window.onload动态添加方法
window.onload = () => {
console.log(1);
}
// 将以后windo.onload 存在_onload变量中
var _onload = window.onload || function (){};
// 新创建一个 window.onload方法
// 如果遇到 this劫持的问题,我们在调用原方法时需要将this通过 apply, call方法制定未正确的this.
window.onload = () => {
_onload();
alert(2);
}

AOP装饰函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
var before = function (fn, beforeFn) {
return function() {
beforeFn.apply(this, arguments);
return fn.apply(this, arguments);
}
}

var after = function (fn, afterFn) {
return function() {
var res = fn.apply(this,arguments);
afterFn.apply(this, arguments);
return res;
}
}

// 数据上报
Function.prototype.after = function (afterFn) {
var _self = this;
return function() {
var ret = _self.apply(this,arguments);
afterFn.apply(this, arguments);
return ret;
}
}

// 打开登录
var showLogin = function () {
console.log('打开登录');
}

// 上报数据
var log = function () {
console.log('上报数据')
}
showLogin = showLogin.after(log); // 打开登录后上报数据

// 用AOP动态修改函数的参数
Function.prototype.before = function (beforeFn) {
var _self = this;
return function () {
beforeFn.apply(this,arguments);
return _self.apply(this,arguments);
}
}

// 原函数
var func = function (param) {
console.log(param);
}
// 执行前的函数
func = func.before(function (param) {
param.b = 'b';
})
// 在before函数 修改了参数
func({a: 'a'});

使用场景

如果原函数需要增加一些和现有功能无关的功能时,为了不破坏已有结构,我们可以通过增加装饰器给原函数增加功能.例如:数据上报、表单提交检验输入值等.