大家好,我是摆烂工程师,今天不摆烂,点杯卡布奇诺,坐下来写一遍关于AOP编程思想的文章。关于AOP的编程,不管在前端还是后端,甚至算法中,都能看到它的身影。我相信大家都写出过这样子的代码。
AOP全称是Aspect Oriented Program, 也就是面向切面编程的意思。字面意思还是比较抽象,我们先来看一小段代码。
const originAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type, listener, opts) {
const wrapperListener = function (...args) {
console.log('练习两年半,真是泰裤辣!');
return listener.apply(this, args);
}
return originAddEventListener.call(this, type, wrapperListener, opts);
}
上面的代码是对一个事件函数进行拦截,再做一层处理。现在我们可以随便给一个DOM元素绑定一个监听事件。触发事件后,都会输出练习两年半,真是泰裤辣!的日志。 而这个对原型链的拦截操作,就是所谓的AOP编程。上面的代码说白了就是在真正的事件执行前,做一些前置操作。而AOP编程,不仅可以做前置操作,还可以做后置操作。也就是代码执行完,还可以在代码后面再做一些其他的处理,比如埋点。
如果你碰到过一个场景,也就是事件监听无法捕获到发生跨域后的错误信息时,那么可以对要执行的函数进行一层try...catch...的封装,如下:
const originAddEventListener = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type, listener, opts) {
const wrapperListener = function (...args) {
try {
return listener.apply(this, args);
} catch (err) {
throw err;
}
}
return originAddEventListener.call(this, type, wrapperListener, opts);
}
上面是前端的AOP编程的小栗子,而平时经常使用AOP的场景更多的是在后端,如Java的注解、Nest.js的装饰器。这些就是用到AOP编程思想的产物。
比如,我们要设计一个权限点控制的功能。那么我们的功能执行之前,是不是要做这个权限点检查呢,而这个权限点检查,就可以通过AOP的编程思想去处理。权限点检查通过执行功能,权限点不通过就报错403等。流程和AOP的行为如图:
而上图的装饰器处理的事情就是AOP切面编程处理的事情。在进入管理员功能之前,做好这些检查。
function right(target, key, descriptor) {
const originFn = descriptor.value;
if (typeof originFn === 'function') {
descriptor.value = async function() {
// 权限检查之后再决定执行功能不。
if (有权限) {
return await originFn.apply(this, arguments);
}
throw 无权限;
}
}
return descriptor;
}
class LoginController {
@right('manage')
manage() {
// doing some operations...
}
}
@right就是处理这个权限的装饰器。不止可以处理权限,还可以处理一下接口缓存等。
上面就是一些AOP切面编程的简单例子。看了这些例子,有没有发现AOP切面编程就是简简单单啦。今天差不多就到这里了,我是摆烂工程师,适当摆烂,让生活靠近你。