裝飾器模式
- 為對象添加新功能
- 不改變其原有的結(jié)構(gòu)和功能
示例

zs1.png

zsuml.png
class Circle {
draw() {
console.log("畫一個(gè)圓形");
}
}
class Decorator {
constructor(circle) {
this.circle = circle;
}
draw() {
this.circle.draw();
this.setRedBorder(circle);
}
setRedBorder(circle) {
console.log("設(shè)置紅色邊框");
}
}
const circle = new Circle();
circle.draw();
const dec = new Decorator(circle);
dec.draw();
場景
ES7 裝飾器
安裝 babel 插件
npm i -D babel-plugin-transform-decorators-legacy
配置.babelrc
- 驗(yàn)證配置
@testDec
class Demo {}
function testDec(target) {
target.isDec = true;
}
console.log(Demo.isDec);
- mixin
function mixin(...list) {
return function(target) {
Object.assign(target.prototype, ...list);
};
}
const Foo = {
foo() {
console.log("foo");
}
};
@mixin(Foo)
class MyClass {}
const obj = new MyClass();
obj.foo();
- 裝飾方法
function readonly(target, name, descriptor) {
descriptor.writable = false;
return descriptor;
}
class Person {
constructor() {
this.first = "A";
this.last = "B";
}
@readonly
name() {
return `${this.first} ${this.last}`;
}
}
// 測試
const p = new Person();
console.log(p.name());
p.name = 1; // 報(bào)錯(cuò), name是只讀的
function log(target, name, descriptor) {
const 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();
console.log(math.add(2, 4));
core-decorators
- 第三方開源 lib
- 提供常用的裝飾器
- 查閱 GitHub文檔

cd1.png

cd2.png

cd3.png
設(shè)計(jì)原則驗(yàn)證
- 將現(xiàn)有對象和裝飾器進(jìn)行分離, 兩者獨(dú)立存在
- 符合開放封閉原則