[zz]AOP重要吗?
作者:zmelody
http://www.iteer.net/modules/newschina/article.php?storyid=186
AOP(Aspect-Oriented Programming)这个领域还很新,不过我乐观地预计,将来很多大项目会采纳AOP方法。在我看来,AOP是非常重要的方向,可能会是软件开发方法发展道路上的“下一个大家伙”。当然,AOP并不是一种取代性的技术,就像现在电视没有取代收音机,电脑也没有取代电视。不过采用AOP方法后,现在许多模式就不再需要了(当然也会出现一批新的模式),软件开发过程也将会改观。
在我看来,软件开发很大程度上是从需求到实现的映射过程。用户不会在意这个系统用了哪些技术,他只会在意系统能否满足他的需求。但是系统构建者的知识结构却是以各种技术为核心的,有人擅长信息安全技术,有人对负载平衡和容错技术具有深厚知识,还有人是数据库专家。如何有效地把需求映射到实现是各种软件开发方法的核心论题。AOP的三菱镜隐喻很好地说明了AOP在这个映射中扮演何种角色,这里不好贴图我就不具体说了。
关注点(concern)的分离,可以让不同的人专注于不同的事(且是他/她擅长的事)。安全专家就带着他的团队编写事关系统安全的那个aspect好了,系统集成专家可以负责与遗产系统整合的相关部分,业务专家则可以集中注意力于business domain。那么构架师呢?他(她)可以负责总体构架,协调如何把这些各自独立的aspects编织(weave)成一个能跑的应用程序。(可以在源代码层编织,也可在byte code层编织。)
我喜欢AOP的理念,但任何技术都不能只停留在理念,其早期实现是非常重要的,甚至关系到技术的存亡。有很多很好的技术,因为一开始没有很好地实现,只好埋入了废纸堆。不仅IT技术如此,自然科学理论也是如此,优秀的理论常常需要实验科学家来验证。(举个例子,我们熟知的两位著名华裔诺贝尔奖获得者身后站着一位优秀的华裔实验科学家,这是众人皆知的美谈。)目前实现AOP的语言中最著名的当属Xerox PARC开发的AspectJ(现移交Eclipse)。我感觉,AspectJ和Java的关系有些类似于当年C with Classes(后来发展成C++)和C的关系;目前的AspectJ的实现也可类比于当年的CFront。当然,我这样说只是一种感觉而已 :)
曾有人把AOP和Interception类比。或许用Interception模式可以模拟AOP吧,但是这不能表示“没必要提出一个新的paradigm”。请问,用C可以模拟C++吗?用struct和函数指针可以模拟class吗?我猜想许多高手可以做到。那么为什么还要有C++和OOP呢?
AOP的编织规则的power不是Interception可轻易实现的。用来指定编织规则的语言和写aspect的语言可以完全不同,不过一般采取的方案是把写aspect的语言后者略作扩展后作为weaver rule specification language。AspectJ就是这样做的。现在也有AspectC,AspectC++。这种做法又让我想起了OOP implementation在C++中的引入。C++对C语言做了扩展,增加了class, private, public, friend, virtual这些新的内容来描述制定类和类间关系的规则,如果没有这些新的关键字,这个规则可不是那么好表述的。而C语言原来的部分也没有被废弃。你看,在成员函数中的如果不定义新的局部类的话,那么不就是差不多用C语言写每个成员函数吗?AspectJ也是如此。你用Java写aspects,用扩展了的Java语言(或者看作新语言也无妨)写weaving rules。这符合用最合适的语言做最适合的事的原则。
回到AOP和Interception的比较。Interception的实现往往是动态的。如果规则的粒度比较粗,指定的interception的粒度又比较细(比如说,一刀切地规定在所有函数的入口和出口intercept),那么效率损失不可忽略。 我举个简化例子,在每个函数第一行和最后一行加上“判断一个intercept函数指针是否为NULL,如果不是NULL就调用它”的代码,那么要做多少次判断呀,其中又有多少次是无功而返呢?而AOP weaver可以静态地编织代码(源代码或者byte code),就不需要付出这一额外代价了,而且intercept的粒度可更加细化。
此外,我感觉用Interception模式,关注点没有很好分离。不像AOP,甚至可以由不同的人用两种语言来做implement aspect和weave aspects这两件事,关注点分得非常清晰。
另外,关于AOP和设计模式,我有一些想法:从不同的编程语言中可以提炼出不同的代码模式(idioms,又译为惯用法),但代码模式是同特定语言相关的,可能有些模式较为通用,但也有些模式在别的语言中就不再需要。比如reference counting模式在支持GC的语言中就不再必要了吧。这不是说代码模式不好,更不是说有了模式,GC就不再必要,只不过是各得其所罢了。不能因为熟悉模式并运用自如就认为新技术没必要。代码模式如此,那么设计模式又何尝不是呢,有些模式比较通用,但也有一些设计模式是和范型相关的,其中又多数以OO相关,没有超脱于OO的框架。(不信?你用C语言或者其他非OO语言实现一遍GoF中的23个模式,看看难度如何,实现是否很自然?POSA v1,v2中的模式可作补充练习。)如果改用AOP,那么很多模式也可自然消亡了,比如interception模式应该就是吧。