前端解读面向切面编程(AOP)

前言

面向对象(OOP)作为经典的设计范式,对于我们来说可谓无人不知,还记得我们入行起始时那句经典的总结吗-万事万物皆对象

是的,基于OOP思想封装、继承、多态的特点,我们会自然而然的遵循模块化、组件化的思维来设计开发应用,以到达易维护、可扩展、高复用的目的。

既然OOP这么多优点,那么经常被大家提起的面向切面编程(AOP)是什么回事呢,下面我们就一起来看一下。

AOP定义

第一步还是要知道aop是什么,先个来自维基百科的解释:

面向侧面的程序设计(aspect-oriented programming,AOP,又译作面向方面的程序设计、观点导向编程、剖面导向程序设计)是计算机科学中的一个术语,指一种程序设计范型。

侧面的概念源于对面向对象的程序设计的改进,但并不只限于此,它还可以用来改进传统的函数。

其从主关注点中分离出横切关注点是面向侧面的程序设计的核心概念。分离关注点使得解决特定领域问题的代码从业务逻辑中独立出来.

业务逻辑的代码中不再含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系通过侧面来封装、维护.

这样原本分散在在整个应用程序中的变动就可以很好的管理起来。

tip

确实有点那么不太清晰,有点乱。不过在乱之前,我们可以选能理解的部分先看一下:

  • 侧面(也就是切面) 用来描述分散在对象、类或函数中的横切关注点

    重点在这,分散在对象中的横切关注点,可以猜一下是什么,应该就是不同对象之间公用的部分

  • 侧面的概念源于对面向对象的程序设计的改进,它还可以用来改进传统的函数.

    AOP 显然不是OOP的替代品,是OOP的一种补充。

  • 从主关注点中分离出横切关注点是面向侧面的程序设计的核心概念。

    具体到业务项目中来说,主关注点就是业务逻辑了。针对特定领域问题代码的调用,就是AOP要关注的部分

简而言之,AOP是针对业务处理过程中的切面(即非业务逻辑部分,例如错误处理,埋点,日志等)进行提取.

它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果(目的是降低耦合)。

具体到实现来说就是通过动态的方式将非主关注点部分插入到主关注点(一般是业务逻辑中)

说了这么多,可能不太明白,还是一起看代码吧。

埋点场景

很普遍的这么个场景,需要点击按钮之后进行信息上报。

假设我们有这么个logger的工具,可以进行上报:

const logger = console.log
//引入即可使用
logger(‘按钮被点击了‘)

那么,我们直接撸起来吧:

const doSomething = ()=>{
    console.log(‘doSomething‘)
}
let clickHandler = ()=>{
   logger(‘doSomething之前‘)
   // n行代码
   doSomething()
   logger(‘doSomething之后‘)
   //n 行代码
}

看起来也没什么的,简单粗暴。

如果有30个按钮,每个业务逻辑不同,都需要埋这个点(假设打点信息一致)。

我们30个函数里面,都要手动写这个方法的话,这也太坑爹了吧。

主要是与业务代码严重耦合,哪天不小心动了点其他内容,手抖误删了,就gg了。

后续维护的时候,简直噩梦。

仔细看一下,这不就是符合AOP的使用前提吗,那么试试AOP吧。

关注点划分

根据前面提的,可以划分下关注点。

主关注点 侧关注点
业务逻辑(doSomething) 埋点信息 logger

前面提到AOP关注的是步骤具体到例子来说其实就是插入logger的步骤。

插入时机无非时业务逻辑执行之前或者之后的阶段。

具体实现起来也不那么困难

实现思路

具体到js来说,由于语言本身的特性,天生就具有运行时动态插入逻辑的能力。

重点在于在原函数上增加其他功能并不改变函数本身。

毕竟函数可以接受一切形式的参数,当然函数也不例外了。

当传入一个函数的时候,我们要对其操作的余地就很大了,

保存原函数,然后利用后续参数加上call或apply,就可以达到我们的目的。

此外为了给函数都增加一个属性,我们在原型上操作就行了。

经典before或者after的实现

网上太多类似实现了,直接看代码好了:

// action 即为我们的侧关注点,即logger
Function.prototype.after = function (action) {
    //保留当前函数,这里this指向运行函数即clickHandler
    var func = this;
    // return 被包装过的函数,这里就可以执行其他功能了。
    // 并且该方法挂在Function.prototype上,
    // 被返回的函数依然具有after属性,可以链式调用
    return function () {
        // 原函数执行,这里不考虑异步
        var result = func.apply(this, arguments);
        // 执行之后的操作
        action.apply(this,arguments);
        // 将执行结果返回
        return result;
    };
};
// before 实现类似,只不过执行顺序差别而已
Function.prototype.before = function (action) {
    var func = this;
    return function () {
        action.apply(this,arguments);
        return func.apply(this, arguments);
    };
};

那么我们使用AOP改造之后的代码就如下了:

const doSomething = ()=>{
    console.log(‘doSomething‘)
}
let clickHandler = ()=>{
   // n行代码
   doSomething()
   //n 行代码
}
clickHandler = clickHandler.before(()=>{
     logger(‘doSomething之前‘)
}).after(()=>{
     logger(‘doSomething之后‘)
})
clickHandler() // 执行结果和预期一致

到这里就实现了面向切面编程,我们的业务逻辑里面只管业务本身,侧关注点通过这种方式来动态引入,与主逻辑解耦,更加纯净、易于维护。

结束语

到这里,简单的AOP就介绍完成了。利用这种模式结合我们js本身的特性,可以尝试更多的可能。

例如我们react中常见的HOC、es7的装饰者模式、HOF等,很多时候不得不感叹大牛们思想的精髓,会让我们有种顿悟的感觉。本文抛砖引玉,共同学习啦,对自己是总结和提高,更希望能帮助到需要的小伙伴。更多文章请移步我的博客

参考文章

AllyTeam - 用AOP改善javascript代码

深入浅出 Javascript Decorators 和 AOP 编程

原文地址:https://www.cnblogs.com/pqjwyn/p/9858352.html

时间: 2024-11-10 20:49:56

前端解读面向切面编程(AOP)的相关文章

Web项目中静态代理和动态代理为基础的面向切面编程AOP

本来每天更新的,我一般喜欢夜里过了十二点的时候发文章,结果难道是愚人节吗?学校的网也很有意思,断了,把我给耍了...好吧-开始今天的话题AOP.AOP太重要了,所以放到第二篇文章来谈这个话题,AOP是Spring中的重要概念.如果这个不理解Web开发中的三大框架的原理,那就呵呵了.时常听到同学和网友议论Web程序员大部分时间都是在考皮XML配置,我当时听到也是醉了,所以我要用心学习Web,其实这里面蕴含的设计模式.算法.架构思想在源码中体现的淋漓尽致啊,一个大宝库竟然视而不见可惜了.下面就一起品

面向切面编程——Aop

一.概念 AOP(Aspect-Oriented Programming,面向切面的编程),它是可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术.它是一种新的方法论,它是对传统OOP编程的一种补充. 二.Aop原理 1.面向对象编程模型 OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分.面向对象编程是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等

Spring(四):面向切面编程AOP

横切关注点:分布于应用中多处的功能 面向切面编程AOP:将横切关注点与业务逻辑相分离 在使用面向切面编程时,仍在一个地方定义通用功能,但是可以通过声明的方式定义这个功能以何种方式在何处应用,而无需修改受影响的类. 横切关注点可以被模块化为特殊的类,这些类被称为切面. 好处: 每个关注点集中于一处,而不是分散到多处代码中 服务模块更加简洁,因为它们只包含主要关注点的代码,次要关注点被转移到切面中了 1.定义AOP术语 1.1.通知(Advice) 切面的工作被称为通知. 通知定义了切面是什么以及何

面向切面编程aop

面向切面编程 (AOP) Aspect Oriented Programming 可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术.AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现. 主要功能 日志记录,性能统计,安全控制,事务处理,异常处理等等 主要意图 将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的

spring中面向切面编程(AOP)的个人理解

面向切面编程AOP,是spring的一大特点 Aspect切面:封装共性功能的(增强功能的)类 Advice通过:切面类中封装的增强功能的方法. PointCut:切入点,是一个集合的概念,该集合的表达使用一个正则表达式表达 所有核心业务对象的所有方法的前后(事务处理AOP典型的应用) JoinPoint:连接点,程序中需要加入advice的地方,而且正在执行的ponitCut 织入(Weaving):将aspect和核心业务对象,进行整合的过程. 通过特定接口实现AOp Aop通知的类型: B

【串线篇】面向切面编程AOP

面向切面编程AOP 描述:将某段代码“动态”的切入到“指定方法”的“指定位置”进行运行的一种编程方式 (其底层就是Java的动态代理)spring对其做了简化书写 场景: 1).AOP加日志保存到数据库 2).AOP做权限验证,filter能做的它都能 3).AOP做安全检查 4).AOP做事务控制 AOP专业术语: 原文地址:https://www.cnblogs.com/yanl55555/p/11744089.html

【转】面向切面编程-AOP,挺有用的

原文:http://blog.csdn.net/yangzhihello/article/details/40377399 下面的代码有点问题, ins[methodName] = function(){      callback.apply(ins,arguments) return method.apply(ins,arguments); } 这段也要放到上面的if 语句块里面去!!! ----------------------------------------------------

Spring面向切面编程(AOP)

1 spring容器中bean特性 Spring容器的javabean对象默认是单例的. 通过在xml文件中,配置可以使用某些对象为多列. Spring容器中的javabean对象默认是立即加载(立即实例化:spring加载完成,立即创建对象) scope:属性 singleton:默认值为单例,默认也是立即加载,在加载完成spring容器的时候,bean对象已经创建完成 prototype:多例的,默认懒加载,spring容器加载完成的时候,不会创建bean的对象,只有从容器获得bean对象的

Spring之面向切面编程AOP(二)

简介 当积累的知识点到一定量的时候,学新知识就变得容易多了.希望再接下来的学习顺利进行下去.今天知识也是挺简单的,主要就是AOP面向切面编程.其中牵涉到了JDKProxy和CGLIB两个代理类,如何使用好,加以深刻理解.学起Spring切面编程也就简单多了 代理模式 1. 代理模式介绍 代理模式的英文叫做Proxy或Surrogate,中文都可译为"代理",所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对