以下是前几日在我csdn的blog上发的一篇翻译文章, 拖了几天还是“未完待续”,
,再过一阵一定翻译完成,英文见:
http://blog.csdn.net/amigoxie/archive/2007/02/10/1506862.aspx
是从网上转载的。
虽翻译得很蹩脚,但因我打算2007年将英语学好,这次也算是点小行动,望大伙鼓励之,别砸我砖头。
AOP != Interception
最近,许多作者在讨论AOP(面向方面编程),但这整个事情是不可置信的强大和精彩。然而,他们中的大部分真正谈论的是一种叫做拦截器的设计模式。这些人并不笨,他们也没有被误导。虽然拦截器从它本身说来是一种强有力的机制,但是它与AOP是不一样的。虽然它们享有许多共同的特征,但是将AOP看成是拦截器就像将OOP看成是数据结构和一堆函数指针。就像直到我们将对象看作仅仅是编码和数据这种观念抛弃之后才真正懂得对象一样,如果我们像真正的懂得在AOP中潜在的巨大能量,我们就需要超越将AOP与拦截器看成是相同的东西的思想。它们在某些点上显然是很有关联的,他们并不是等价的。
一.定义
对初学者来说,因为90%的参数是基于语法的差异性,让我们首先确定一下几个术语。
1)面向切面编程
i) "面向切面的软件发展是一种在软件发展中备受关注的新技术,AOSD报文交换集中技术使得模块化一个系统的方方面面成为可能。" -AOSD主页
ii) "AOP的主要思想是虽然面向对象程序语言中层级化的模块化机制已经非常的有用,但是他们天生无
法将复杂系统的所有方面都模块化。相应地,我们相信""
2)拦截器
"拦截器架构模式允许能够透明的加入到框架中,并能够在某事件发生的时候自动的触发"--软件架构模式。乍一看,这两个东西出奇的相似,拦截器在一个确定的执行点执行,主要用来在它拦截到一个对象方法时能提供额外的行为,并且形成了在对象的切入点之上通过在源码中增加声明式的切入点来添加额外的行为。虽然有如此多的事情,但是,它们的细节真正体现在细节和明显的层下。但是,作为讨论的一部分,为了真正的看到为什么它们交迭了如此多我们再需要定义几个术语。
1)分离的关注点:一个关注点从本质上来说当我们需要在我们的软件系统上建立模块时是一个自动的事情。例如,在一个财会系统中,资产概念就是一个切入点,因此,我们尝试和捕获将与资产相关的所有概念变成我们在OO系统中调用的对象时的连贯的事情。这个使得我们更好地跟踪系统中地提取物,允许我们随着时间的流逝能更好地维护。每一种程序设计语言含蓄地将这个作为它们的中心目标,即使这些关注点本身和它们应该怎样地捕获存在很大的不同。
2)横切关注点:横切关注点,像在面向方面的著作中所说的那样,是系统中的一部分,在标准的对象模型语义学中,它不能通过默认的构造函数捕获。例如,考虑跟踪一个方法的入口和出口。通常来说,我们通过类本身来达到这个目标,例如我们可以通过如下方式:
if (Debugging.isEnabled())
Debugging.trace("Method foo() entered");// . . .
if (Debugging.isEnabled())
Debugging.trace("Method foo() exiting");
就像我们可以想象的那样,这种行为捕可以通过基类继承或者通过提供一个对另一个类的内部引用来实现(OO系统建造一个干净的分离的关注点的规范化的方式是通过继承或合成),每一个想要跟踪的方法都要包含这4行语句。另外,更负责的是,横向切入点在企业系统中的通用用法包括持久化(这点与旧有的对象关系是不一样的),同步行为(我们的对象在多线程中应该怎么处理),以及远程化(当我们的对象允许通过进程边界进行调用时我们应该怎样处理)。所列的这些问题在传统的面向对象环境中都不能清楚地被捕获。
拦截器和AOP
拦截器模式来自POSA2,没有更好地定义出来时,我一直引用规范化定义, 这个问题是"发展容易扩展的框架",这种解决方案如下:
允许应用程序通过注册"频带外"的通过预先定义的接口带有框架的服务对框架进行清晰地扩展,并允许框架在这些事件发生时自动的触发这些服务(注:在本文种,"事件"指的是应用级别的事件,例如在ORB框架中传输请求和回应。这些事件通常只在框架实现中是可见的)。另外,打开框架的实现,以便外面的服务能够对框架行为的各方面进行进入和控制。
换句话说,拦截器常隐含的包含如下东西
1.显式的支持拦截器系统:POSA2将其叫做框架,COM+,.NET,servlets和EJB在它们的容器边界做这些事情,但是它们潜在的思想是一样的--在某些地方,某些种类的构造器是那些提供拦截器行为的构造器,显然将拦截器调用流作为通用处理的一部分。这就意味着。。。。。。。例如,在servlet框架中(开始于servlet2.3规范),拦截器通过过滤器提供,允许些servlet的人有机会拦截对servlet和jsp(或任意url)的请求和回应。但是,拦截器仅能用于对url请求和呼应进行控制,因此过滤器不能够做到如下东西,例如:拦截不能调用普通的java类或者通过像RML或其他系统等渠道调用。
2. 请求/回应渠道的概念:拦截器与请求/回应语义学产生了很重要的依赖关系,自从拦截器常常用来在方法的入口和出口完成某些功能,这就意味着很大数量的相互影响是非接触的或难以获得的(如果这有点抽象,有赖于--这个可能更易理解)。
3. 拦截器在一个运行时构造器中差不多是普及的:POSA2显式的指出,这些服务概念的引用在所有的情况下避过那不都是许亚好的,因此拦截器的行为不能静态的分层化--它必须在运行时注册。不幸运的是,这也意味着一定数量的运行时超载,特别地,如果拦截器事件模型是粗糙的。例如,在.NET的上下文对象架构中,方法调用既在既在对象外部,又在通过IMessageSink-and-friends架构能够进行拦截的上下文内部。但是,一旦注册,上下文拦截器必须在任意方法的进入和进出上下文时被调用;没有可选的其他方式来指明这个拦截器只对某种类型的方法有效。
(未完待续)
posted on 2007-02-13 17:14
阿蜜果 阅读(1219)
评论(3) 编辑 收藏 所属分类:
Spring