持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第13天,点击查看活动详情
前言
装饰者模式:在不改变原对象的基础上,通过对其进行包装拓展(添加属性或者方法)使原有对象可以满足用户的更复杂需求。
这都2022年了,相信大家对ES6已经很熟悉了。在ES6中提到了一个新的语法——装饰器,用来注释或修改类和类方法。
没错,相信机智的你已经知道我要说什么了。装饰器其实就是一种变相的装饰器模式。
装饰器
假设我们有这样一个用来描述人的类——Person,这个类有个name方法用来获取这个人的完整姓名。
class Person {
name() {
return `${this.first} ${this.last}`;
}
}
这个时候我们需要处理这个方法添加日志,以方便我们知道什么时候获取过这个人的姓名,然后上报给日志系统。
function log(target, name, descriptor) {
const oldValue = descriptor.value;
descriptor.value = function() {
// ...上报
return oldValue.apply(this, arguments);
};
return descriptor;
}
看到这里,就要引出我们下一位登场的主角了——劫持函数。是的,装饰器其实也运用了函数劫持这个方法。相信这个时候大家也可以得出一个新的结论了:函数劫持也是装饰器模式的运用。
函数劫持
假设我们在做小程序端日志相关的功能,这个时候我们就需要收集错误信息然后上报给服务端。但是,如果收集错误信息呢?
大多数的错误都会冒泡的onError事件中来,但是,通过查找文档我们发现,微信小程序的脚本错误和api错误都会触发APP.onError钩子,所以我们就可以在onError钩子中做处理。
App {
onError(msg) {
// 上报错误
...
}
}
但是,这种方式对业务代码的侵入比较强,而且跟业务逻辑进行了耦合。随着业务的发展,最终有可能会朝着代码屎山的方向发展,这个时候我们就需要使用装饰器模式对代码进行优化处理。
const originError = App.onError;
App.onError = function (..agus) {
// 上报错误
originError.apply(this, agus);
}
结语
相信到这里大家已经对装饰器模式很熟悉了,这里我们再进行总结一下。装饰器模式是对原有函数功能不影响的前提下,进行新的功能的增强与拓展。
好了,有关装饰器模式的内容我们就聊到这里了,希望对大家有所帮助。欢迎大家在下方进行留言交流。