1.什么是装饰器模式
Decorator Design Pattern:
当我们拍了一张照片准备发朋友圈时,我们会选择给照片加上滤镜。同一张照片、不同的滤镜组合起来就会有不同的体验。这实际上就是装饰者模式:是通过滤镜装饰了照片。在不改变对象(照片)的情况下,动态的为其添加功能(滤镜),而且通过不同的装饰器组合(不同的滤镜组合),可以达到叠加的效果。
需要注意的是:由于 JavaScript 语言动态的特性,我们很容易就能改变某个对象。但是我们要尽量避免直接改写某个函数,这违反了开闭原则。js里函数也是对象因此js中的装饰器模式,实际上是装饰的是函数。
2.使用AOP装饰函数
回到上面的例子,因为装饰的是函数,因此改为给拍照片这个动作(而不是照片)添加滤镜功能。
// AOP函数
const after = function(fn, afterFn) {
return function (...args) {
const ret = fn.apply(this, args);
afterFn.apply(this, args);
return ret;
}
}
// 原函数
const takePhoto = function(){
console.log('拍照片');
}
// 装饰函数
const addFilter = function(){
console.log('添加滤镜');
}
takePhoto = after(takePhoto, addFilter);
takePhoto();
3.基于类的原型对象装饰类里的方法
/**
*
* @param {*} target 类
* @param {*} action 类里的方法名
* @param {*} afterFn 装饰函数
*/
function after(target, action, afterFn) {
oldAction = target.prototype[action];
if (oldAction) {
target.prototype[action] = function (...args) {
const ret = oldAction.apply(this, args);
afterFn.apply(this, args);
return ret;
}
}
}
class PhotoUtils {
takePhoto() {
console.log('拍照片');
}
}
function addFilter() {
console.log('添加滤镜')
}
const pu = new PhotoUtils();
after(PhotoUtils, 'takePhoto', addFilter);
pu.takePhoto();
4.ES和TS中的装饰器
目前Decorator
在语言里还处于提案阶段,想用但不敢用啊
参考文献
https://mp.weixin.qq.com/s/WcoX4H4LLgyvr8ELxcE6FQ
《JavaScript设计模式和开发实践》