前端解读面向切面编程(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指向运行函数即clickHandlervar 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 编程
前端解读面向切面编程(AOP)相关推荐
- Spring in Action 入门之面向切面编程AOP
注明:这篇文章一是当成学习笔记,二是给大家提供另一个快速理解学习Spring的参考.欢迎留言讨论,持续更新中~ (该部分是Spring的面向切面编程AOP) 第四章 通知Bean 在软件编程中,散布于 ...
- 服务端第三次课程:面向切面编程AOP
3:面向切面编程AOP 1:回顾 bean的组装方式 规划的装配 component autowired sacn是在configuration底下的 Java config 使用configurat ...
- Spring-学习笔记08【面向切面编程AOP】
Java后端 学习路线 笔记汇总表[黑马程序员] Spring-学习笔记01[Spring框架简介][day01] Spring-学习笔记02[程序间耦合] Spring-学习笔记03[Spring的 ...
- Spring→面向切面编程AOP、相关概念、通知Advice类型、配置切面切入点通知、AOP相关API、AOP代理类ProxyFactoryBean、AOP注解@AspectJ
面向切面编程AOP CGLib AOP相关概念 Advice类型 Spring实现AOP Spring配置切面aspect 配置切入点pointcut 配置通知advice 配置通知参数 调用新的父类 ...
- Spring(四):面向切面编程AOP
2019独角兽企业重金招聘Python工程师标准>>> 横切关注点:分布于应用中多处的功能 面向切面编程AOP:将横切关注点与业务逻辑相分离 在使用面向切面编程时,仍在一个地方定义通 ...
- Spring之面向切面编程AOP(八)
介绍&步骤 视频教程: https://www.bilibili.com/video/BV1WZ4y1P7Bp?p=121 官方笔记链接:https://pan.baidu.com/s/1dn ...
- 九、面向切面编程AOP
本栏博客目录 一.Spring的IOC和DI 二.IoC和DI注解开发 三.SpringMVC入门 四.SpringMVC的请求和响应 五.JdbcTemplate 六.Spring练习 七.Spri ...
- java切面编程 切面概念,面向切面编程(AOP)初探
面向对象编程通过设计和语言本身提供的模块化.封装.继承.多态来实现软件复用.尽管OOP在建模以及实现复杂软件方面非常成功,它仍然有一些问题.面向切面编程(AOP)被认为是一项有前途的新技术,它通过对交 ...
- 【Spring】面向切面编程AOP
AOP基础 什么是AOP [废话解释]在软件业,AOP全称Aspect Oriented Programming 即:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AO ...
最新文章
- 密码界“女杀手”,破译世上最安全密码系统,获 771 万奖金!
- 关于SWT开发的一个坑——Invalid thread access
- linux mmap 详解【转】
- 2010年度报告:是谁在编写Linux内核?
- C++断言与静态断言
- 搜索引擎的那些事(摘取价格数据)
- 职场白骨精必看的五个寓言
- H3C nat转换实验
- Linux下编译hiredis
- 数字逻辑电路课程设计之数字电子时钟
- 基于C#制作的简易代码生成器
- 回忆真是一个痛苦的过程
- DLL中无法定位程序输入点inflateReset2于动态链接库
- python 爬虫 短信验证码
- 测试sd卡读写速度与判断是否是扩容的假货
- 软工导第一节课 计算机软件工程学作一个简短的概述,回顾计算机系统发展简史 软件工程的基本原理和方法有概括的本质的认识,详细讲解生命周期相关知识讲解8种典型的软件过程模型
- UCK Network 以用户至上、体验为王为核心, 打造完善的综合体验平台
- UltraISO Premium Edition9.7.1.3519完美破解版
- .globl伪操作符
- solidity第一课—了解Remix和Hellosolidity三行代码