面向切面编程--AOP(转)
2014-04-15 13:28
351 查看
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/
直接上代码:
func_section decorator代码
如何使用?
还不明白?我来举个最简单的例子。
现在有个函数叫做eat(),业务逻辑就是饿了要吃饭,而且已经很多地方调用它了。现在我有个需求,在每次吃饭之前我要吃点开胃菜before_eat(),吃饭之后,我要刷牙洗口after_eat()。怎么实现呢?
评价:确实完成了功能。但是违反了开闭原则,而且函数耦合性很高,如果以后添加了更多需求,这段代码会臃肿不堪,业务逻辑复杂到一定规模的时候,你就祈祷神来解决你吧。
评价:违反了封装原则,这一系列操作对外应该是不可见的。我都懒得评价了。。
这样,以后业务逻辑增加了,只需要将原子的业务逻辑加入函数执行链中即可。体验到它的强大了吧?
原文: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 | def func_section(before_chain=[], after_chain=[]): def func_wrap(func): def wrap(*args, **kwargs): for before_func in before_chain: try: before_func(*args, **kwargs) except Exception: continue res = func(*args, **kwargs) for after_func in after_chain: try: after_func(*args, **kwargs) except Exception: continue return res return wrap return func_wrap |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1819 | def example(): def before_saying(self): print("I know your name %s" % self.name) def before_saving(self): print("I will notify your name %s" % self.name) def after_saving(self): print("After saving your name %s " % self.name) def done(self): print("Everything is ok %s " % self.name) class FuncTest(): def __init__(self, name): self.name = name def __i_know_you(self): print("I know you guy %s " % self.name) @func_section(before_chain=[__i_know_you, before_saying, before_saving], after_chain=[after_saving, done]) def save(self): print("Save name %s " % self.name) return self.name test = FuncTest(name=u'chenchiyuan') print(test.save()) >>> example() I know you guy chenchiyuan I know your name chenchiyuan I will notify your name chenchiyuan Save name chenchiyuan After saving your name chenchiyuan Everything is ok chenchiyuan chenchiyuan |
看了这么多,它能干什么?
它的作用就是减少你的代码的耦合度还不明白?我来举个最简单的例子。
现在有个函数叫做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 | def before_eat(): print(u'吃开胃菜') def after_eat(): print(u'刷牙') @func_section(before_chain=[before_eat, ], after_chain=[after_eat, ]) def eat(): print(u'吃饭') |
题外话
1. Django中有没有类似的方式?
肯定是有的,最接近的其实是signal的实现。把model.save()比喻成eat(), 那么你可以通过Django自带的before_save, after_save来实现在save的切面前后添加业务逻辑。这样做远远比你重写save方法好得多。2. 还有什么注意的东西?
顺便提提对象的方法实现。instance.do_something(args, **kwargs)。在切面编程拿到的形式是do_something(instance, args, **kwargs)。这其实就是面向对象的最核心的实现技巧。相关文章推荐
- 使用Spring进行面向切面(AOP)编程
- Spring AOP:面向切面编程简介
- Aspects iOS的AOP面向切面编程的库
- spring学习--面向切面编程AOP和AspectJ
- js实现面向切面的编程(AOP)
- 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-使用工厂创建代理(Using the ProxyFactoryObject to create AOP proxies)
- Spring面向切面编程AOP
- SpringAop 9 (面向切面编程,常用于拦截器)
- 面向切面编程AOP的浅显理解(三)
- 【spring-boot】spring aop 面向切面编程初接触
- 【面向切面编程_AOP】
- spring-05 之AOP 面向切面编程 一
- Spring面向切面编程——Spring实现AOP方式——通过Spring API实现
- 面向切面编程--AOP
- 【转】面向切面编程-AOP,挺有用的
- AOP面向切面编程简介
- 转:面向切面编程AOP的理解
- Spring面向切面编程AOP
- AOP面向切面编程 - 淘宝京东网络处理
- Spring配置过程 (二)面向切面编程AOP