装饰器模式
为对象添加新功能
不改变其原有的结构和功能
传统 UML 类图
javascript 中的装饰器
装饰类
@testDec
clss Demo {
}
function testDec(target) {
target.isDec = true
}
alert(Demo.isDec)
@testDec(false)
clss Demo {
}
function testDec(isDec) {
return function (target) {
target.isDec = isDec
}
}
alert(Demo.isDec)
装饰器原理
@decorator
class A {}
//等同于
class A {}
A = decorator(a) || A;
装饰类-mixin 示例
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'
装饰方法
one
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 是只读属性
two
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);
core-decorators
- 第三方开源 lib
- 提供常用的装饰器
- 文档
- 执行
npm i core-decorators --save
使用
想用什么装饰器,直接引入就行了
one
import { readonly } from "core-decorators";
class Person {
@readonly
name() {
return "zhang";
}
}
let p = new Person();
alert(p.name());
// p.name = function () { /*...*/ } // 此处会报错
two
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.
设计原则验证
- 将现有对象和装饰器进行分离,两者独立存在
- 符合开放封闭原则