# 装饰者模式

  • 动态地给某个对象添加一些额外的职责,是一种实现继承的替代方案
  • 在不改变原对象的基础上,通过对其进行包装扩展,使原有对象可以满足用户的更复杂需求,而不会影响从这个类中派生的其他对象

# 什么是 AOP

AOP(Aspect-Oriented Programming):面向切面编程,是对 OOP 的补充。利用 AOP 可以对业务逻辑的各个部分进行隔离,也可以隔离业务无关的功能比如日志上报、异常处理等,从而使得业务逻辑各部分之间的耦合度降低,提高业务无关的功能的复用性,也就提高了开发的效率。

在 JavaScript 中,我们可以通过装饰者模式来实现 AOP,但是两者并不是一个维度的概念。 AOP 是一种编程范式,而装饰者是一种设计模式。

下面是一个例子:

class IPhone {
    constructor(name) {
        this.name = name || "iphone";
    }
    takePhoto() {
        console.log("拍照");
    }
    getName() {
        console.log("获取名称");
        return this.name;
    }
}
class MiPhone {
    constructor(name) {
        this.name = name || "xiaomi";
    }
    takePhoto() {
        console.log("拍照");
    }
    getName() {
        console.log("获取名称");
        return this.name;
    }
}
class RedMiPhone extends MiPhone {
    constructor(name) {
        super()
        this.name = name || "xiaomi";
    }
}
// after AOP
function after(target, action, fn) {
    let old = target.prototype[action];
    if (old) {
        target.prototype[action] = function() {
            let handle = old.call(this);
            fn.call(this, handle);
        };
    }
}
// 用 AOP 函数修饰原函数
after(IPhone, "takePhoto", function() {
    console.log("添加滤镜");
});

after(IPhone, "getName", function(name) {
    console.log(name);
});

after(MiPhone, "getName", function(name) {
    console.log(name);
});
let myPhone = new IPhone("suporka iphone");
myPhone.getName();
let myPhone2 = new MiPhone("suporka mi phone");
myPhone2.getName();
let myPhone3 = new RedMiPhone('suporka redmi phone')
myPhone3.getName()
console.log(myPhone3)
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
56
57
58
59

通过 after 函数修饰 IPhone 和 MiPhone 使其增加其他功能