Thursday, November 17, 2005
AOP之我見
前言
AOP就是Aspect Oriented Programming,有人把它翻作「面向導向程式設計」,是一種新的程式設計方法。雖然目前AOP的發展還沒有完全成熟,相關的理論與技術也是鮮為人知,不過某些AO的基本概念早就已經進入主流領域中,而開始漸漸被大家所注意。
從軟體設計演化史看AOP
AOP之所以會出現,必定是有一段歷史的。
程式語言的演化是從機器語言(machine-level language)、程序性程式設計(procedural programming)、物件導向程式設計(object oriented programming)到現在的AOP。到底是為什麼會這樣演化的呢?
根據我自己認為,在機器語言演化到程序性語言的過程,是因為那些使用機器語言的程式設計師想到了他們可以運用數學函數的概念,把一些為了做某件事而相關的敘述擺在同一個函式中,再對函式進行叫用,藉以達成了功能的抽象化。
後 來這些寫程序性語言的程式設計師在不滿足之餘,發現到了他們居然可以將現實生活中,物件的概念應用到原來的程序性語言,對它進行物件抽象化。像是他們只看 得到電視機的外殼和一些訊號輸入裝置、按鈕,卻看不到其內部的電路板與陰極放射管,於是乎產生了資料封裝和介面的概念;他們看到了自己跟自己的父母、阿公 阿媽、外公外婆之間好像有著某種程度的相似關係,但彼此間卻又不完全一樣,瞭解到了長江後浪是要去推前浪的,而有了繼承的想法;當然其它像是以訊息傳遞、 多型等物件導向的特性也同時一併結合起來,為程式語言提供強大、有彈性的性質,進而讓物件導向程式設計成為當今程式設計領域中的主要潮流。
而 當這些物件導向程式設計師開始建構越來越大、越來越複雜的系統、搞出了一堆有的沒的設計模式後,發現了原來軟體系統中有許多功能是零碎地散佈在其它功能之 間;某些功能又是為了提供一些附屬的服務而必須加入許多與該功能無關的程式碼進去而顯得雜亂。因為這些發現,造成了這些人很大的困擾,讓他們很難進行開 發、維護、擴充、以及再利用,原因即是在於既有物件導向的特性並沒有辦法以很好的方式去解決這種現象,迫使他們必須要以各種骯髒手法來處理這些問題。於是 這些被弄得很難過的其中某些高手就想出了AOP這個厲害的新型軟體設計方法來進行考量(concern)的抽象化。
AOP的目標與概念
軟體系統的設計會包含許多的考量(concern)。所謂的考量,就是為了滿足整體系統目標的一個特定需求。遠在七零年代,就有人認為若是想把一個軟體系統搞得好,就必須要將功能分離(separation of concerns,SOC),也就是所謂模組化的概念。這個概念並不算新,但是說起來容易;做起來難。
某些介紹AOP的書上對SOC的概念有個較為具體的詮釋,就是把系統的需求當做一道自然光束,當這道光透過一個能夠區分功能的三稜鏡後,發散出來的每一種不同波長、不同顏色的小光束就是代表系統中某個維度被分離出來的一種功能。當然,這是一個簡化後的比喻。
回到現實,我們設計一套軟體系統,最重要的就是它的主要功能(core concern),不管是早期的程序性語言或是物件導向語言都是為此目標發展的。然而橫跨系統中多個模組的共通功能(crosscutting concern)則是AOP想要處理的目標。
我再用另外一種方式來描述AOP。物件導向語言中的物件可以儲存資料,也提供了處理這些資料的方法、動作,就像是一般自然語言中的名詞與動詞。而AOP則是在現有物件的資料、方法上增加特性,這就有點類似自然語言中的形容詞與副詞了。所以物件導向技術再加上面向導向技術所提供的,就會是一個更完整的解決方式。
AOP對軟體設計的影響
AOP是基於SOC這種分離功能的概念而發展的產物,但我認為此種想法,通常會是在較為大型、或是十分複雜的系統中才有實行的必要,不然感覺上就像是用牛刀來殺雞般不切實際。
我們會因為多了此種實作共通功能的考量,導致在系統分析、設計的思維都必須與傳統物件導向或程序導向的思維不同,需要好好地洗腦一下。
現實的情況應該是許多從C語言此種程序性語言開始學習的人,還是把像是C++、Java這類物件導向語言拿來當作程序性語言來寫,完全沒有將分析設計的方法、概念轉換過來。
物件導向程式設計有一套OOAD流程,而現在多了一個AOP的概念,想必花在分析、設計的時間與精力又要比原來更多、更困難。
AOP的分析設計大致上分為三項:aspectual decomposition(面向分割)、concern implementation(功能實作)以及aspectual recomposition(面向重組)。而又因為AOP要解決的共通功能,理所當然是要應用在主要功能之上。所以原來的物件導向分析設計一樣也不能少,還必須想辦法在原本的設計流程中加入上面的三個面向的考量,必須要調整原有的使用案例、也不能光用標準的UML來表達系統架構,而要另外找一個方式來表達面向(aspect),就連許多現存設計模式的實作,也與之前大不相同。
目前就有一些探討AOP、AOSD的書籍、文章開始像雨後春筍般大量產生。就連物件導向三巨頭之一的Jacobson也參一腳出了一本。有趣的是他在書中提到,現在所謂AOP的概念,早在1985年他為他自己博士論文的未來目標所寫的一篇論文中有提到,只不過當時連物件的概念都還沒有盛行,引不起大家的注意,所以這項研究也沒有繼續下去。後來AOP在1997年正式出現時,他也有注意到,但由於他那時正忙著設計UML與RUP,導致於錯失了一個成為AOP之父的機會,真的是蠻可惜的,不過對他來說應該也沒有差吧。
最後,AOP不會取代物件導向程式設計或程序性設計,也就是說良好的AO設計必定是要建構在良好的物件導向設計、程序性設計之上,不然仍無法對系統的實作產生任何助益。
以下是從書上摘要出來的AOP優缺點:
AOP的優點
- 單一模組的責任更簡單
- 更好的模組化
- 系統更容易發展
- 設計上更有彈性
- 程式的重利用率更高
- 加快開發
- 減少實作成本
AOP的缺點
- 更難掌握程式執行的流程
- 破壞封裝
結論
AOP會是解決軟體開發問題的一顆銀彈嗎?
我覺得不會,它跟物件導向程式設計一樣,解決的是軟體開發中的附屬性問題,雖然它跟物件導向程式設計結合的威力是前所未見的,但是要如何進行AOSD?如何辨識出不同的面向?該怎麼樣正確地決定到底是要用類別、還是面向?都還是有待研究的。所以我想它跟物件導向程式設計一樣是顆銅彈吧。
AOP對一般的程式設計師來說,是個更高難度的轉換、更痛苦的開端。
不過從另一個角度來想,現在會去玩AOP的應該也不會是一般平庸的程式設計師,所以讓它順其自然地發展,等時機慢慢成熟,可能就會在不久的將來改變軟體界。
參考資料
- Ivar Jacobson and Pan-Wei Ng, Aspect-Oriented Software Development with Use Cases, Addison Wesley 2005, ISBN: 032126881
- Ramnivas Laddad, AspectJ in Action - Practical Aspect-Oriented Programming, Manning 2003, ISBN: 1930110936
- Gregor Kiczales and Mira Mezini, Separation of Concerns with Procedures, Annotations, Advice and Pointcuts, Proceedings of ECOOP'05
- Gregor Kiczales and Mira Mezini, Aspect-Oriented Programming and Modular Reasoning, Proceedings of ICSE'05
- Jan Hannemann and Gregor Kiczales, Design Pattern Implementations in Java and AspectJ, Proceedings of OOPSLA 2002
- Boris Bachmendo and Rainer Unland, Aspect-Based Workflow Evolution
- Anis Charfi and Mira Mezini, Application of Aspect-Oriented Programming to Workflows: The case of Web Service Composition with AO4BPEL