最近看到一个比较好玩的东西:AOP(Aspect Oriented Programming),叫做面向切面编程,旨在降低程序之间的耦合行,属于设计模式中的装饰者模式,今天就来看看它的实现和主要用途。

实现

它的原理就是通过对原方法的封装,以before,after,around方式添加扩展,实现代码如下:

现在看不懂啥意思没关系,待会会讲解具体的使用场景。

方法劫持

假设多人开发一个页面,然后有人已经在window.onload方法里面写了很多东西,这个时候你也想在window.onload里面加点东西,但是又不想直接在window.onload代码里面加(这样大家的逻辑比较容易搞混,而且也比较容易起冲突),该咋办呢?这个时候我们就要用到方法劫持了,平常我们可能如下去劫持:

上面的方式确实可以实现劫持,但是浪费了一个变量,通过AOP的后置通知就可以无缝实现这种功能,代码看起来是这样的:

AOP的后置通知就是在当前方法执行完成后再去执行另一个方法,这种写法对window.onload方法没有侵入,也没有浪费变量去劫持。

其实如果我们去看_after的源码可以发现实现的原理也和我们上面实现的差不多,先执行自身方法,然后执行了传入的方法,只不过自身方法是通过__self.apply(__self, arguments)执行,而不是通过劫持。

计算时间差

平常我们计算一段程序的执行时间一般都会在方法的开头和结束时去计算当前时间,然后计算两者的差得出一段程序执行的时间,可能如下:

这种方法通常不太好,因为这种是侵入式的,也就是说你这个统计的代码完全和业务没有关系,假如你要统计另一个方法的,你还得这样写一遍。

用AOP的前置通知和后置通知可以解决这个问题,前置通知就是在当前方法执行前先去执行一个方法;后置通知就是当前方法之后去执行一个方法,我们可以利用这个实现统计时间的功能,代码看起来可能是这样:

这种写法看起来复杂了不少,但是却是无侵入式的,不会去修改你的业务逻辑代码,不想统计了,也可以很快删除;如果是侵入式的统计时间,那么得要小心翼翼的删除那些代码,一不小心可能会影响到业务逻辑代码。

表单到验证和提交

表单提交是很常见的需求,平常我们的写法可能如:

我们把表单的验证单独放在一个方法里,然后在提交的时候验证是否通过,如果通过,接下来就传输数据,如果失败就报错。

这种做法对于submit方法来说,还是有一些侵入式的,因为submit里面最好只放提交的方法,而不要放验证的方法,这种情况可以用AOP的环绕通知来接耦,代码可能如:

可以看到,我们把submit中的验证步骤提出来了,放到了_around方法里面,_around方法很有意思,它把当前方法(submit)的执行权给提出来(交给了fn),如果要调用,就要通过fn.invoke()方法触发,就相当于把当前方法给包裹起来,想不想调用通过传入的方法去控制。

这样可以把两个方法的业务逻辑剥离的更干净,把耦合的部分放到了外面,大大降低了耦合性。

最后

上面关于AOP的实现不是唯一的,只是为了方便,把它放到了Function.prototype上,还有很多种实现方式,现实中的场景也要自己多思考才能派上用场。

其他文章

0
我要评论

评论

返回
×

我要评论

回复:

昵称:(昵称不超过20个字)

图片:

提交
还可以输入500个字