AOP的理解

 
AOP簡介
 
  AOP:advance online publication.在線雜誌出版物。
  面向切面編程:Aspect Oriented Programming
  AOP是OOP的延續,是(Aspect Oriented Programming)的縮寫,意思是面向切面編程。
  主要的功能是:日誌記錄,性能統計,安全控制,事務處理,異常處理等等。
  主要的意圖是:將日誌記錄,性能統計,安全控制,事務處理,異常處理等代碼從業務邏輯代碼中劃分出來,通過對這些行爲的分離,我們希望可以將它們獨立到非指導業務邏輯的方法中,進而改變這些行爲的時候不影響業務邏輯的代碼。
  可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。AOP實際是GoF設計模式的延續,設計模式孜孜不倦追求的是調用者和被調用者之間的解耦,AOP可以說也是這種目標的一種實現。
  在Spring中提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如審計(auditing)和事務(transaction)管理)進行內聚性的開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們並不負責(甚至是意識)其它的系統級關注點,例如日誌或事務支持。 
 
應用舉例
 
  假設有在一個應用系統中,有一個共享的數據必須被併發同時訪問,首先,將這個數據封裝在數據對象中,稱爲Data Class,同時,將有多個訪問類,專門用於在同一時刻訪問這同一個數據對象。
  爲了完成上述併發訪問同一資源的功能,需要引入鎖Lock的概念,也就是說,某個時刻,當有一個訪問類訪問這個數據對象時,這個數據對象必須上鎖Locked,用完後就立即解鎖unLocked,再供其它訪問類訪問。
  使用傳統的編程習慣,我們會創建一個抽象類,所有的訪問類繼承這個抽象父類,如下:
  abstract class Worker{
  abstract void locked();
  abstract void accessDataObject();
  abstract void unlocked();
  } 
 
缺點:
 
  accessDataObject()方法需要有“鎖”狀態之類的相關代碼。
  Java只提供了單繼承,因此具體訪問類只能繼承這個父類,如果具體訪問類還要繼承其它父類,比如另外一個如Worker的父類,將無法方便實現。
  重用被打折扣,具體訪問類因爲也包含“鎖”狀態之類的相關代碼,只能被重用在相關有“鎖”的場合,重用範圍很窄。
  仔細研究這個應用的“鎖”,它其實有下列特性:
  “鎖”功能不是具體訪問類的首要或主要功能,訪問類主要功能是訪問數據對象,例如讀取數據或更改動作。
  “鎖”行爲其實是和具體訪問類的主要功能可以獨立、區分開來的。
  “鎖”功能其實是這個系統的一個縱向切面,涉及許多類、許多類的方法。如下圖:
  因此,一個新的程序結構應該是關注系統的縱向切面,例如這個應用的“鎖”功能,這個新的程序結構就是aspect(方面)
  在這個應用中,“鎖”方面(aspect)應該有以下職責:
  提供一些必備的功能,對被訪問對象實現加鎖或解鎖功能。以保證所有在修改數據對象的操作之前能夠調用lock()加鎖,在它使用完成後,調用unlock()解鎖。 
 
AOP應用範圍
 
  很明顯,AOP非常適合開發J2EE容器服務器,目前JBoss 4.0正是使用AOP框架進行開發。
  具體功能如下:
  Authentication 權限
  Caching 緩存
  Context passing 內容傳遞
  Error handling 錯誤處理
  Lazy loading 懶加載
  Debugging 調試
  logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準
  Performance optimization 性能優化
  Persistence 持久化
  Resource pooling 資源池
  Synchronization 同步
  Transactions 事務
  【AOP有必要嗎?】
  當然,上述應用範例在沒有使用AOP情況下,也得到了解決,例如JBoss 3.XXX也提供了上述應用功能,但是沒有使用AOP。
  但是,使用AOP可以讓我們從一個更高的抽象概念來理解軟件系統,AOP也許提供一種有價值的工具。可以這麼說:因爲使用AOP結構,現在JBoss 4.0的源碼要比JBoss 3.X容易理解多了,這對於一個大型複雜系統來說是非常重要的。
  從另外一個方面說,好像不是所有的人都需要關心AOP,它可能是一種架構設計的選擇,如果選擇J2EE系統,AOP關注的上述通用方面都已經被J2EE容器實現了,J2EE應用系統開發者可能需要更多地關注行業應用方面aspect。 
 
AOP具體實現
 
  AOP是一個概念,並沒有設定具體語言的實現,它能克服那些只有單繼承特性語言的缺點(如Java),目前AOP具體實現有以下幾個項目:
  AspectJ (TM): 創建於Xerox PARC. 有近十年曆史,成熟
  缺點:過於複雜;破壞封裝;需要專門的Java編譯器。
  動態AOP:使用JDK的動態代理API或字節碼Bytecode處理技術。
  基於動態代理API的具體項目有:
  JBoss 4.0 JBoss 4.0服務器
  nanning 這是以中國南寧命名的一個項目,搞不清楚爲什麼和中國相關?是中國人發起的?
  基於字節碼的項目有:
  aspectwerkz ,spring
 
AOP 能夠給我們帶來什麼
  面向過程編程離我們已經有些遙遠,面向對象編程正主宰着軟件世界。當每個新的軟件設計師都被要求掌握如何將需求功能轉化成一個個類,並且定義它們的數據成員、行爲,以及它們之間複雜的關係的時候,面向方面編程(Aspect-Oriented Programming,AOP)爲我們帶來了新的想法、新的思想、新的模式。
  如果說面向對象編程是關注將需求功能劃分爲不同的並且相對獨立,封裝良好的類,並讓它們有着屬於自己的行爲,依靠繼承和多態等來定義彼此的關係的話;那麼面向方面編程則是希望能夠將通用需求功能從不相關的類當中分離出來,能夠使得很多類共享一個行爲,一旦發生變化,不必修改很多類,而只需要修改這個行爲即可。
  面向方面編程是一個令人興奮不已的新模式。就開發軟件系統而言,它的影響力必將會和有着十數年應用歷史的面向對象編程一樣巨大。面向方面編程和麪向對象編程不但不是互相競爭的技術而且彼此還是很好的互補。面向對象編程主要用於爲同一對象層次的公用行爲建模。它的弱點是將公共行爲應用於多個無關對象模型之間。而這恰恰是面向方面編程適合的地方。有了 AOP,我們可以定義交叉的關係,並將這些關係應用於跨模塊的、彼此不同的對象模型。AOP 同時還可以讓我們層次化功能性而不是嵌入功能性,從而使得代碼有更好的可讀性和易於維護。它會和麪向對象編程合作得很好。
   AOP 的應用範圍
  傳統的程序通常表現出一些不能自然地適合單一的程序模塊或者是幾個緊密相關的程序模塊的行爲,AOP 將這種行爲稱爲橫切,它們跨越了給定編程模型中的典型職責界限。橫切行爲的實現都是分散的,軟件設計師會發現這種行爲難以用正常的邏輯來思考、實現和更改。最常見的一些橫切行爲如下面這些:
  日誌記錄,跟蹤,優化和監控
  事務的處理
  持久化
  性能的優化
  資源池,如數據庫連接池的管理
  系統統一的認證、權限管理等
  應用系統的異常捕捉及處理
  針對具體行業應用的橫切行爲
  目前,前面幾種橫切行爲都已經得到了密切的關注,也出現了各種有價值的應用,但也許今後幾年,AOP 對針對具體行業應用的貢獻會成爲令人關注的焦點。
  AOP 的具體實現
  AOP 是一個概念,一個規範,本身並沒有設定具體語言的實現,這實際上提供了非常廣闊的發展的空間。AspectJ是AOP的一個很悠久的實現,它能夠和 Java 配合起來使用。
  介紹 AspectJ 的使用和編碼不是本文的目的,你可以在 Google 上找到很多有關它的材料。
  這裏只是重溫 AspectJ 中幾個必須要了解的概念:
  Aspect: Aspect 聲明類似於 Java 中的類聲明,在 Aspect 中會包含着一些 Pointcut 以及相應的 Advice。
  Joint point:表示在程序中明確定義的點,典型的包括方法調用,對類成員的訪問以及異常處理程序塊的執行等等,它自身還可以嵌套其它 joint point。
  Pointcut:表示一組 joint point,這些 joint point 或是通過邏輯關係組合起來,或是通過通配、正則表達式等方式集中起來,它定義了相應的 Advice 將要發生的地方。
  Advice:Advice 定義了在 pointcut 裏面定義的程序點具體要做的操作,它通過 before、after 和 around 來區別是在每個 joint point 之前、之後還是代替執行的代碼。
  下面要討論的這些問題,也許正是接觸了 AOP 之後所困惑的。
  AOP 幫助我們解決了新的問題沒有?
  AOP 並沒有幫助我們解決任何新的問題,它只是提供了一種更好的辦法,能夠用更少的工作量來解決現有的一些問題,並且使得系統更加健壯,可維護性更好。同時,它讓我們在進行系統架構和模塊設計的時候多了新的選擇和新的思路。
  AOP 和 OOP 到底是什麼關係
  很多人在初次接觸 AOP 的時候可能會說,AOP 能做到的,一個定義良好的 OOP 的接口也一樣能夠做到,我想這個觀點是值得商榷的。AOP和定義良好的 OOP 的接口可以說都是用來解決並且實現需求中的橫切問題的方法。但是對於 OOP 中的接口來說,它仍然需要我們在相應的模塊中去調用該接口中相關的方法,這是 OOP 所無法避免的,並且一旦接口不得不進行修改的時候,所有事情會變得一團糟;AOP 則不會這樣,你只需要修改相應的 Aspect,再重新編織(weave)即可。 當然,AOP 也絕對不會代替 OOP。核心的需求仍然會由 OOP 來加以實現,而 AOP 將會和 OOP 整合起來,以此之長,補彼之短。
  AOP 適合工業化的應用嗎?
  這個問題很難回答,其實最好的答案就是嘗試,用成功的項目或是產品來回答。Jboss 4.0 就是完全採用 AOP 的思想來設計的 EJB 容器,它已經通過了 J2EE 的認證,並且在工業化應用中證明是一個優秀的產品。相信在不遠的將來,會出現更多采用 AOP 思想設計的產品和行業應用。
 
小結
  AOP 正向我們走來,我們需要關注的是怎麼樣使得它能夠爲我們的軟件系統的設計和實現帶來幫助。本文旨在給大家一點啓發,能夠在更多的領域更深入的應用 AOP 的思想。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章