Appearance
装饰器模式
介绍
- 为对象添加新功能
- 不改变其原有的结构和功能
传统 UML 类图

简化 UML 类图

javascript
class Circle {
draw(){
console.Log("画一个圆形")
}
}
class Decorator {
constructor(circle) {
this.circle = circle
}
draw() {
this.circle.draw()
this.setRedBorder(circle)
}
setRedBorder(circle){
console.log('设置红色边框')
}
}
// 测试代码
let circle = new Circle()
circle.draw()
let dec = new Decorator(circle)
dec.draw()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
场景 - 装饰类
javascript
//一个简单的 demo
@testDec
class Demo {
// ...
}
function testDec(target) {
target.isDec = true;
}
alert(Demo.isDec) // true
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
javascript
// 装饰器的原理
@decorator
class A {}
// 等同于
cLass A {}
A = decorator(A) || A;
1
2
3
4
5
6
7
2
3
4
5
6
7
装饰器 - mixin 示例
javascript
function mixins(...list) {
return function (target) {
Object.assign(target.prototype, ...list)
}
}
const Foo = {
foo() { alert('foo') }
}
@mixins(Foo)
class MyClass {}
let obj = new MyClass();
obj.foo() // 'foo'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
场景 - 装饰方法
装饰方法一例 1
javascript
function readonly(target, name, descriptor){
// descriptor对象原来的值如下
// {
// value: specifiedFunction,
// enumerable: false,
// configurable: true,
// writable: true
// };
descriptor.writable = false;
return descriptor;
}
class Person {
constructor() {
this.first = 'A'
this.last = 'B'
}
@readonly
name() { return `${this.first} ${this.last}` }
}
var p = new Person()
console.log(p.name())
p.name = function () {} // 这里会报错,因为 name 是只读属性
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
装饰方法一例 2
javascript
function log(target, name, descriptor) {
var oldValue = descriptor.value;
descriptor.value = function() {
console.log(`Calling ${name} with`, arguments);
return oldValue.apply(this, arguments);
};
return descriptor;
}
class Math {
@log
add(a, b) {
return a + b;
}
}
const math = new Math();
const result = math.add(2, 4);
console.log('result', result); // add [Object] //result 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
core-decorators 的使用
javascript
// import { readonly } from 'core-decorators'
// class Person {
// @readonly
// name() {
// return 'zhang'
// }
// }
// let p = new Person()
// alert(p.name())
// // p.name = function () { /*...*/ } // 此处会报错
import { deprecate } from 'core-decorators';
class Person {
@deprecate
facepalm() {}
@deprecate('We stopped facepalming')
facepalmHard() {}
@deprecate('We stopped facepalming', { url: 'http://knowyourmeme.com/memes/facepalm' })
facepalmHarder() {}
}
let person = new Person();
person.facepalm();
// DEPRECATION Person#facepalm: This function will be removed in future versions.
person.facepalmHard();
// DEPRECATION Person#facepalmHard: We stopped facepalming
person.facepalmHarder();
// DEPRECATION Person#facepalmHarder: We stopped facepalming
//
// See http://knowyourmeme.com/memes/facepalm for more details.
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
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
设计原则验证
- 将现有对象和装饰器进行分离,两者独立存在
- 符合开放封闭原则