面向切面编程--AOP(转)
add by zhj:面向切面编程就是在不修改函数A的前提下,在函数A前后插入业务逻辑B, C, D..。这其实算是功能分解,将大模块S=A+B+C+D+……分解为独立的小功能A,B,C,D……,模块化可使得功能复用、低耦合,不过这种分解也不是粒度越细越好。
原文:http://blog.zoneke.com/blog/2012/12/25/qie-mian-bian-cheng/
什么是面向切面编程?
面向切面编程, Aspect Oriented Programming(AOP)。主要实现的是将业务逻辑处理过程以切面为维度进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。也就是说,在不修改函数A的前提下,在函数A前后插入业务逻辑B, C, D..
基于Python Decorator的切面编程
Python的decorator功能很强大,它能在运行期间拿到函数的上下文,并且赋予你足够的权限去做很多事情。这恰恰符合面向切面编程的设计方式,你可以通过decorator方便的实现这个功能。
直接上代码:
func_section decorator代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
|
如何使用?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
|
看了这么多,它能干什么?
它的作用就是减少你的代码的耦合度
还不明白?我来举个最简单的例子。
现在有个函数叫做eat(),业务逻辑就是饿了要吃饭,而且已经很多地方调用它了。现在我有个需求,在每次吃饭之前我要吃点开胃菜before_eat(),吃饭之后,我要刷牙洗口after_eat()。怎么实现呢?
1. 懒人的方法
管它三七二十一,直接修改eat(), 先加上before_eat(), 再加上after_eat()。
评价:确实完成了功能。但是违反了开闭原则,而且函数耦合性很高,如果以后添加了更多需求,这段代码会臃肿不堪,业务逻辑复杂到一定规模的时候,你就祈祷神来解决你吧。
2. 最笨的方法
全文搜索,找出所有用到eat()的地方,前面加上before_eat(),后面加上after_eat()。
评价:违反了封装原则,这一系列操作对外应该是不可见的。我都懒得评价了。。
3. 优雅的方法
使用面向切面编程的方法。
1
2
3
4
5
6
7
8
9
|
|
这样,以后业务逻辑增加了,只需要将原子的业务逻辑加入函数执行链中即可。体验到它的强大了吧?
题外话
1. Django中有没有类似的方式?
肯定是有的,最接近的其实是signal的实现。把model.save()比喻成eat(), 那么你可以通过Django自带的before_save, after_save来实现在save的切面前后添加业务逻辑。这样做远远比你重写save方法好得多。
2. 还有什么注意的东西?
顺便提提对象的方法实现。instance.do_something(args, **kwargs)。在切面编程拿到的形式是do_something(instance, args, **kwargs)。这其实就是面向对象的最核心的实现技巧。