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模式應該就是吧。