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
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
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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)。这其实就是面向对象的最核心的实现技巧。

面向切面编程--AOP(转)的更多相关文章

  1. 设计模式之面向切面编程AOP

    动态的将代码切入到指定的方法.指定位置上的编程思想就是面向切面的编程. 代码只有两种,一种是逻辑代码.另一种是非逻辑代码.逻辑代码就是实现功能的核心代码,非逻辑代码就是处理琐碎事务的代码,比如说获取连 ...

  2. Spring学习手札(二)面向切面编程AOP

    AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...

  3. Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)

    一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...

  4. Spring框架学习笔记(2)——面向切面编程AOP

    介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...

  5. Spring之控制反转——IoC、面向切面编程——AOP

      控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...

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

    面向切面编程AOP 描述:将某段代码“动态”的切入到“指定方法”的“指定位置”进行运行的一种编程方式 (其底层就是Java的动态代理)spring对其做了简化书写 场景: 1).AOP加日志保存到数据 ...

  7. 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制

    spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...

  8. [译]如何在ASP.NET Core中实现面向切面编程(AOP)

    原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...

  9. Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)

    在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...

  10. 面向切面编程AOP

    本文的主要内容(AOP): 1.AOP面向切面编程的相关概念(思想.原理.相关术语) 2.AOP编程底层实现机制(动态代理机制:JDK代理.Cglib代理) 3.Spring的传统AOP编程的案例(计 ...

随机推荐

  1. Oracle的闪回技术--闪回已删除的表

    注意闪回技术只能保护非系统表决空间中的表,而且表空间必须本地管理, 外键将不可以被恢复, 索引和约束的名字将会被命名为以BIN开头,由系统生成的名字 查看是否开启闪回: SQL> show pa ...

  2. API权限控制与安全管理

     摘自网上 一.API权限控制范围 1.首先验证web端请求参数: (1)web请求参数:渠道.ServiceName.版本.Airline.时间戳(yyyyMMddhhmmssSSS).reqXML ...

  3. 【delphi】delphi出现‘尚未调用CoInitialize’异常

    1. 由于使用ado等引起的异常. 2. 若是子线程或某方法操作ado可在该方法开头和结尾分别加上: function myfun begin CoInitialize(nil); // your c ...

  4. 二、K3 WISE 开发插件《 工业单据老单客户端插件事件、属性、方法》

    ===================== 目录: 1.插件事件说明如下 2.插件属性说明如下 3.插件方法说明如下 ===================== 1.插件事件说明如下:  序号 事   ...

  5. css笔记 - 张鑫旭css课程笔记之 border 篇

    border地址 border特性: 能形成BFC但是不能清除浮动.但是bfc也是把子元素的margin包裹进来,但是拿自己的margin穿透没办法的. 边框宽度不支持百分比 透明border可以突破 ...

  6. 常见的mysql 进程state<转自网络>

    Analyzing 线程是对MyISAM 表的统计信息做分析(例如, ANALYZE TABLE ). checking permissions 线程是检查服务器是否具有所需的权限来执行该语句. Ch ...

  7. 简单了解如何使用vue-router和vue-resource

    我们先来看看vue-router 1.npm install vue-router --save 2.调用vue-router: 第一种方法: 直接在main.js中调用 import vueRout ...

  8. Sencha Touch 实战开发培训 视频教程 第二期 第八节 (完结)

    2014.4.23 晚上8:00左右开课. 本节课耗时超长,因为演示过程中出现了一些小错误,所以耗时接近2小时. 本期培训一共八节,前两节免费,后面的课程需要付费才可以观看. 本节内容: 开发cord ...

  9. POJ 2456 Aggressive cows(二分答案)

    Aggressive cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 22674 Accepted: 10636 Des ...

  10. Rsync未授权访问漏洞的利用和防御

    首先Rsync未授权访问利用 该漏洞最大的隐患在于写权限的开启,一旦开启了写权限,用户就可以,用户就可以利用该权限写马或者写一句话,从而拿到shell. 我们具体来看配置文件的网相关选项(/etc/r ...