面向切面编程
什么是面向切面编程
AOP(Aspect Orient Programming)是一种设计思想,它是对面向对象编程(OOP)的一种补充和完善。它以通过预编译方式或运行期动态代理方式,实现在不修改源代码的情况下给程序动态统一添加额外功能的一种技术。核心思想是将类中与核心业务逻辑不太相关的通用功能切面式的提取出来,让多个类共享这个行为,当需要改变这个行为时不必修改全部的类,而只需要单独修改这个行为。
AOP就是要基于OCP(开闭原则),在不改变原有系统核心业务代码的基础上动态添加一些扩展功能并可以"控制"对象的执行。例如AOP应用于项目中的日志处理,事务处理,权限处理,缓存处理等等。如图
实现举例
function logic(){
for (let t = Date.now(); Date.now() - t \< 10;){
// Nothing
}
console.log('End: '+new Date().getTime());
}
方法抽出
class LogUtil {
printTs(prefix) {
console.log(prefix + new Date().getTime());
}
}
class Demo {
constructor(log) {
this.log = log;
}
logic() {
this.log.printTs('Star: ');
for (let t = Date.now(); Date.now() - t \< 10;) {
// Nothing
}
this.log.printTs('End: ');
}
}
new Demo(new LogUtil()).logic();
静态代理方式
class LogUtil {
printTs(prefix) {
console.log(prefix + new Date().getTime());
}
}
class Demo {
logic() {
for (let t = Date.now(); Date.now() - t \< 10;) {
// Nothing
}
}
}
class StaticProxyDemo extends Demo {
constructor(proxy, loggger) {
super();
this.loggger= loggger;
this.proxy = proxy;
}
logic() {
this.loggger.printTs('Star: ');
this.proxy.logic();
this.loggger.printTs('End: ');
}
}
new StaticProxyDemo(new Demo(), new LogUtil()).logic();
动态代理
class LogUtil {
printTs(prefix) {
console.log(prefix + new Date().getTime());
}
}
class Demo {
logic() {
for (let t = Date.now(); Date.now() - t \< 10;) {
// Nothing
}
}
}
class DynamicProxy {
constructor(before, proxy, after) {
this.before = before;
this.proxy = proxy;
this.after = after;
}
execute() {
this.before();
this.proxy.logic();
this.after();
}
}
let log = new LogUtil();
let proxy = new DynamicProxy(() =\> {
log.printTs('Star: ');
},
new Demo(),
() =\> {
log.printTs('End: ')
});
proxy.execute();