掀起掀起AOP的盖头来的盖头来
面向对象技术很好地解决了软件系统中角色划分的问题。借助于面向对象的分析、设计和实现技术,开发者可以将问题领域
的“名词”转换成软件系统中的对象,从而很自
然地完成从问题到软件的转换.
但是,问题领域的某些需求却偏偏不是用这样的“名词”来描述的.我的一个朋友就曾经遇到这样的问题:需要对系统中的某
些方法进行日志记录,这种需要记录方法
散布在40多个类中。面对这种需求,应该怎么办呢?最直接的办法就是:创建一个起类(或接口),将日志的功能放在其
中,并让所有需要日志功能的类继承这个起类(或接口).如果这个需求是后期提出的.需要修改的地方就会分散在40多个
文件(如果是C+十,这个数量还可能加倍)中。这样大的修改量,无疑会增加出错的几率,并且加大系统维护的难度。
人们认识到,传统的程序经常表现出一些不能自然地适合单个程序模块或者几个紧密相关的程序模块的行为 例如日志记
录、对上下文敏感的错误处理、性能优化以及设计模
式等等、我们将这种行为称为“横切关注点(crosscuttingconcern)”,因为它跨越了给定编程模型中的典型职责界限。如果使
用过用于核切关注点的代码,您就会知道缺乏模块性所带来的问日。因为横切行为的实现是分散的,开发人员发现这种行为难
以作逻辑思维、实现和更改.
因此,面向方面的编程(Aspect-OrientedProgramming,AOP)应运而生。AOP为开发者提供了一种描述横切关注点的机
制,并能够自动将横切关注点织入到面向对象的软件系统中,从而实现了横切关注点的模块化.通过划分Aspect代码,横切
关注点变得容易处理。开发者可以在编译时更改、插入或除去系统的Aspect,甚至重用系统的Aspect.
更重要的是,AOP可能对软件开发的过程造成根本性的影响。我们可以想象这样一种情况:OOP只用于表示对象之间的泛化
一特化(generalization-specialization)关系(通过继承来表现),而对象之间的校向关联则完全用AOP来表现。这样,很
多给对象之间横向关联增加灵活性的设计模式(例如Decorator、Role Object等)将不再必要.
一种编程思想是否真正优秀,只有从实现语言上才能看到。施乐公司帕洛阿尔托研究中心(Xerox PARC)开发了第一个AOP
的开发环境——AsPectJ ,这个工具提供了一整套的语法,能够清楚地描述横切关注点,并将其织入到Java源代码中。织入
后的代码仍是标准Java代码,因此AspectJ不会影响Java的移植能力。此外,AspectJ提供了一个独立的IDE,并且能够嵌入
到Jbuilder、Forte等Java开发环境之中,无缝地提供AOP的能力。关于AspectJ,读者可以在http://www.aspectj.org找到更
多的信息。
但是,现在的AOP还处于相当不完善的阶段:它只能应用于很少的几种语言环境下,并且必须掌握源代码才能进行织入.但
以RUP之父Ivar Jacobson为代表的科学家们仍对AOP推崇备至:他认为AOP将最终改变整个软件开发的方式,并且更完美地
实现“用例驱动”的开发思想.
利用利用AOP分离软件关注点分离软件关注点
一个关注点(concern)就是一个特定的目的,一块我们感兴趣的区域。从技术的角度来说,一个典型的软件系统包含一些核心
的关注点和系统级的关注点。举个例子来说,一个信用卡处理系统的核心关注点是借贷/存入处理,而系统级的关注点则是日
志、事务完整性、授权、安全及性能问题等,许多关注点——我们叫它横切关注点(crosscutting concerns)——会在多个模
块中出现,使用现有的编程方法,横切关注点会横越多个模块,结果是使系统难以设计、理解、实现和演进。
AOP能够比上述方法更好地分离系统关注点,从而提供模块化的横切关注点。
在这篇文章里,我首先会解释横切关注点在软件系统中引起的问题,接着我会介绍AOP是怎样解决横切关注点问题的。
软件编程方法的演进软件编程方法的演进
在计算机科学的早期阶段,开发人员使用简单的机器级代码来编程。不幸的是,程序员得花费更多时间来考虑一种特定机器
的指令集而不是手中需要解决的问题本身。慢慢地,我们转而使用允许对底层机器做某种抽象的高级语言。然后是结构化语
言,我们可以把问题分解成一些必要的过程来完成任务。但是,随着复杂程度的增加,我们又需要更适合的技术。面向对象的
编程方式(OOP)使我们可以把系统看作是一批相互合作的对象。类允许我们把实现细节隐藏在接口下。多态性为相关概念
提供公共的行为和接口,并允许特定的组件在无需访问基础实现的前提下改变特定行为。
编程方法和语言决定了我们和计算机交流的方式。每一种新的方法学都提出一种新的分解问题的方法:机器码、伪代码、过程
和类等。每种新的方法学都使得从系统需求到编程概念的映射更加自然。编程方法学的发展让我们可以建立更加复杂的系统,
这名话反过来说也地,我们能够建立更加复杂的系统是加为这些技术允许我们处理这种复杂度。
现在,大多数软件项目都选择OOP的编程方式。确实,OOP已经表明了它处理一般行为的能力,但是,我们将会看到(或许
你已经感觉到了):OOP不能很好地处理横越多个——经常是不相关的——模块的行为。相比之下,AOP填补了这个空白,
它很可能会是编程方法学发展的一个里程碑。
把系统看作一批关注点把系统看作一批关注点
我们可以把一个复杂的系统看作是由多个关注点来组合实现的。一个典型的系统可能会包括几个方面的关注点,如业务逻
辑、性能,数据存储、日志和调度信息、授权、安全、线程、错误检查等,还有开发过程中的关注点,如易懂、易维护、易追
查、易扩展等,图1演示了由不同模块实现的一批关注点组成一个系统。