AOP(程序功能维护技术)

2023-01-26 58阅读

温馨提示:这篇文章已超过465天没有更新,请注意相关的内容是否还可用!

AOP

程序功能维护技术

在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。

面向切面编程(AOP)作为面向对象编程的补充和完善,通过把横切代码织入到业务组件,能够很好地解决"横切关注点"问题。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

AOP在其他领域也有其他含义。

中文名面向切面编程
外文名Aspect Oriented Programming
简称AOP
属性软件开发技术
衍生范型函数式编程
又意葡萄酒

名称含义

Aspect Oriented Programming(AOP)是较为热门的一个话题。AOP,国内大致译作“面向方面编程”。

“面向方面编程”,这样的名字并不是非常容易理解,且容易产生一些误导。不止一次听到类似“OOP/OOD11即将落伍,AOP是新一代软件开发方式”这样的发言。显然,发言者并没有理解AOP的含义。Aspect,没错,的确是“方面”的意思。不过,华语传统语义中的“方面”,大多数情况下指的是一件事情的不同维度、或者说不同角度上的特性,比如我们常说:“这件事情要从几个方面来看待”,往往意思是:需要从不同的角度来看待同一个事物。这里的“方面”,指的是事物的外在特性在不同观察角度下的体现。而在AOP中,Aspect的含义,可能更多的理解为“切面”比较合适。所以更倾向于“面向切面编程”的译法。

可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现。

在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

主要功能

日志记录,性能统计,安全控制,事务处理,异常处理等等

主要意图

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

联系区别

区分

AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。

而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异。

上面的陈述可能过于理论化,举个简单的例子,对于“雇员”这样一个业务实体进行封装,自然是OOP/OOD的任务,我们可以为其建立一个“Employee”类,并将“雇员”相关的属性和行为封装其中。而用AOP设计思想对“雇员”进行封装将无从谈起。

同样,对于“权限检查”这一动作片断进行划分,则是AOP的目标领域。而通过OOD/OOP对一个动作进行封装,则有点不伦不类。换而言之,OOD/OOP面向名词领域,AOP面向动词领域。

关系

很多人在初次接触AOP的时候可能会说,AOP能做到的,一个定义良好的OOP的接口也一样能够做到,这个观点是值得商榷的。AOP和定义良好的OOP的接口可以说都是用来解决并且实现需求中的横切问题的方法。但是对于OOP中的接口来说,它仍然需要我们在相应的模块中去调用该接口中相关的方法,这是OOP所无法避免的,并且一旦接口不得不进行修改的时候,所有事情会变得一团糟;AOP则不会这样,只需要修改相应的Aspect,再重新编织(weave)即可。当然,AOP也绝对不会代替OOP。核心的需求仍然会由OOP来加以实现,而OP将会和OOP整合起来,以此之长,补彼之短。

主要缺点

accessDataObject方法需要有“锁”状态之类的相关代码。

Java只提供了单继承,因此具体访问类只能继承这个父类,如果具体访问类还要继承其它父类,比如另外一个如Worker的父类,将无法方便实现。

重用被打折扣,具体访问类因为也包含“锁”状态之类的相关代码,只能被重用在相关有“锁”的场合,重用范围很窄。

功能特性

仔细研究这个应用的“锁”,它其实有下列特性:

“锁”功能不是具体访问类的首要或主要功能,访问类主要功能是访问数据对象,例如读取数据或更改动作。

“锁”行为其实是和具体访问类的主要功能可以独立、区分开来的。

“锁”功能其实是这个系统的一个纵向切面,涉及许多类、许多类的方法。如下图:

因此,一个新的程序结构应该是关注系统的纵向切面,例如这个应用的“锁”功能,这个新的程序结构就是aspect(方面)

在这个应用中,“锁”方面(aspect)应该有以下职责:

提供一些必备的功能,对被访问对象实现加锁或解锁功能。以保证所有在修改数据对象的操作之前能够调用lock(加锁),在它使用完成后,调用unlock(解锁)。

应用范围

很明显,AOP非常适合开发J2EE容器服务器,目前JBoss4.0正是使用AOP框架进行开发。

具体功能如下:

Authentication:权限

Caching:缓存

Contextpassing:内容传递

Errorhandling:错误处理

Lazyloading:懒加载

Debugging:调试

logging,tracing,profilingandmonitoring:记录跟踪、优化、校准

Performanceoptimization:性能优化

Persistence:持久化

Resourcepooling:资源池

Synchronization:同步

Transactions:事务

【AOP有必要吗?】

当然,上述应用范例在没有使用AOP情况下,也得到了解决,例如JBoss3.XXX也提供了上述应用功能,但是没有使用AOP。

但是,使用AOP可以让我们从一个更高的抽象概念来理解软件系统,AOP也许提供一种有价值的工具。可以这么说:因为使用AOP结构,现在JBoss4.0的源码要比JBoss3.X容易理解多了,这对于一个大型复杂系统来说是非常重要的。

从另外一个方面说,好像不是所有的人都需要关心AOP,它可能是一种架构设计的选择,如果选择J2EE系统,AOP关注的上述通用方面都已经被J2EE容器实现了,J2EE应用系统开发者可能需要更多地关注行业应用方面aspect。

【AOP实现项目】

AOP是一个概念,并没有设定具体语言的实现,它能克服那些只有单继承特性语言的缺点(如Java),目前AOP具体实现有以下几个项目:

AspectJ(TM):创建于XeroxPARC.有近十年历史,成熟。

缺点:过于复杂;破坏封装;需要专门的Java编译器。

动态AOP:使用JDK的动态代理API或字节码Bytecode处理技术。

基于动态代理API的具体项目有:JBoss4.0JBoss4.0服务器

基于字节码的项目有:aspectwerkz,spring

具体作用

面向过程编程离我们已经有些遥远,但它正主宰着软件世界。当每个新的软件设计师都被要求掌握如何将需求功能转化成一个个类,并且定义它们的数据成员、行为,以及它们之间复杂的关系的时候,面向切面编程(Aspect-Oriented Programming,AOP)为我们带来了新的想法、新的思想、新的模式。

如果说面向对象编程是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和多态等来定义彼此的关系的话;那么面向切面编程则是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。

面向切面编程是一个令人兴奋不已的新模式。就开发软件系统而言,它的影响力必将会和有着数十年应用历史的面向对象编程一样巨大。面向切面编程和面向对象编程不但不是互相竞争的技术而且彼此还是很好的互补。面向对象编程主要用于为同一对象层次的公用行为建模。它的弱点是将公共行为应用于多个无关对象模型之间。而这恰恰是面向切面编程适合的地方。有了AOP,我们可以定义交叉的关系,并将这些关系应用于跨模块的、彼此不同的对象模型。AOP同时还可以让我们层次化功能性而不是嵌入功能性,从而使得代码有更好的可读性和易于维护。它会和面向对象编程合作得很好。

具体实现

AOP是一个概念,一个规范,本身并没有设定具体语言的实现,这实际上提供了非常广阔的发展的空间。AspectJ是AOP的一个很悠久的实现,它能够和Java配合起来使用。

介绍AspectJ的使用和编码不是本文的目的,你可以在Google上找到很多有关它的材料。

这里只是重温AspectJ中几个必须要了解的概念:

Aspect:Aspect声明类似于Java中的类声明,在Aspect中会包含着一些Pointcut以及相应的Advice。

Jointpoint:表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它jointpoint。

Pointcut:表示一组jointpoint,这些jointpoint或是通过逻辑关系组合起来,或是通过通配、正则表达式等方式集中起来,它定义了相应的Advice将要发生的地方。

Advice:Advice定义了在pointcut里面定义的程序点具体要做的操作,它通过before、after和around来区别是在每个jointpoint之前、之后还是代替执行的代码。

下面要讨论的这些问题,也许正是接触了AOP之后所困惑的。

AOP帮助我们解决了新的问题没有?

AOP并没有帮助我们解决任何新的问题,它只是提供了一种更好的办法,能够用更少的工作量来解决现有的一些问题,并且使得系统更加健壮,可维护性更好。同时,它让我们在进行系统架构和模块设计的时候多了新的选择和新的思路。

工业化应用

这个问题很难回答,其实最好的答案就是尝试,用成功的项目或是产品来回答。Jboss4.0就是完全采用AOP的思想来设计的EJB容器,它已经通过了J2EE的认证,并且在工业化应用中证明是一个优秀的产品。相信在不远的将来,会出现更多采用AOP思想设计的产品和行业应用。

参考资料

1.在Spring面向切面编程及其应用研究·中国知网

目录[+]