跳轉到內容

計算機程式設計/面向切面程式設計

來自華夏公益教科書,自由的教科書,共享知識

面向切面程式設計 (AOP) 是對 面向物件程式設計 (OOP) 的後續發展,旨在解決 OOP 的一些實際侷限性。

OOP 旨在透過將資料和方法封裝到離散物件中來管理軟體開發的複雜性,減少不同軟體構造之間的依賴關係,以及多型性,即能夠將不同的程式構造在特定目的下視為相同。總的來說,定義一組構建良好的物件,它們之間具有明確的關係,使程式設計師能夠將軟體“元件化”,以小規模、簡單、專注的方式工作,建立易於安全地組合成更大構造以實現更多功能的構造。

OOP 在實踐中的困難在於,在任何大型應用程式中,都有一些方面不容易分解成物件/元件,或者不容易用作物件/元件。“橫切關注點”,或稱為 _橫切點_,是大型軟體專案中存在於幾個地方或多個物件中的部分,其中實現程式碼來有效地解決這些關注點會導致封裝失效,並增加而不是減少依賴關係。AOP 旨在透過將處理這些橫切點的程式碼移動到單獨的程式設計構造中來減少依賴關係和複雜性,然後這些構造可以透過 _織入器_ 以自動化方式織回 OOP 原始碼。結果是面向物件的程式碼可以像往常一樣編譯。

AOP 的一個典型例子是日誌記錄。程式設計師通常使用日誌記錄來記錄程式的狀態和流程,以便在開發期間進行除錯,並在部署後進行錯誤修復。在 OOP 程式中,這有幾種可能的形式

  • 每個物件都可以訪問一個全域性日誌記錄物件,並呼叫其方法來記錄事件或狀態。
  • 所有需要日誌記錄的物件都重複相同的程式碼來寫入日誌。
  • 每個物件都維護自己的日誌,可能寫入檔案。

這裡 AOP 試圖解決的關鍵問題是,程式碼在幾個地方重複出現,這使得維護變得困難,並增加了不同構造之間的依賴關係。更改日誌記錄器的行為需要在第二和第三種情況下對多個檔案中的相同程式碼進行重寫;更改日誌記錄器的使用需要在所有情況下對相同程式碼進行重寫。

透過將日誌記錄定義為一個橫切點,並使用一個切面來解決這個問題,程式設計師編寫切面程式碼來處理日誌記錄,並利用一個 _織入器_ 將程式碼注入到 OOP 原始碼中,然後像普通 OOP 程式碼一樣編譯。日誌記錄功能已從類的原始碼中移除,放在一個位置,並被視為另一個可以區域性定義和實現的單一構造,然後可以在程式的其餘部分中離散地使用。

從理論上講,AOP 是實現 _關注點分離_ 的方法。物件通常被要求處理幾個概念上不同的關注點。銷售條目應用程式中的發票包含一些明顯屬性,例如購買者的身份和購買的商品;但發票物件可能還需要知道如何記錄其操作,如何將自己持久化到資料庫中,如何驗證購買者的信用額度,以及如何在其逾期時發出標記。因此,發票類可能會變得很大、很複雜,而且難以維護。這些關注點中的每一個對該類來說都是合法的處理物件,但根據 OOP 的原則,必須在內部進行處理,並且是不可見的。如果這些關注點由其他關係較遠的物件共享,那麼不僅涉及的類具有不必要的複雜性,而且這種複雜性在多個地方重複。

以下幾個定義將有所幫助

一個 _橫切關注點_,或 _橫切點_,是指 OOP 應用程式設計中的任何部分,這些部分同時出現在 OOP 應用程式的幾個不同部分,這些部分本身之間沒有關聯。日誌記錄是一個明顯的例子,但持久化也是另一個例子:在銀行應用程式中,許多不同的物件必須以相同的方式儲存和檢索(例如,關係資料庫)。持久化是對應用程式物件的橫切點。

一個 _連線點_ 是 OOP 程式碼中織入器可以識別的一個語義上可定義的點。以我們的日誌記錄示例為例,程式設計師可能希望記錄呼叫棧,因此日誌記錄器應該記錄每個函式的進入和退出。

一組連線點透過 _切入點_ 標識:連線點是織入器實際識別的程式碼中的位置;切入點是定義要查詢的連線點的 AOP 程式碼。

切入點不僅標識連線點,還包含對這些點進行操作的程式碼。程式碼稱為 _通知_ 或 _通知_。

那麼,_切面_ 就是一組切入點,定義了一個特定的橫切點,由 AOP 模組處理。實際上,我們對日誌記錄示例的解決方案是一個切面模組,它定義了切入點,標識了程式設計師希望記錄日誌的連線點。在標識了連線點之後,程式設計師將通知寫入 AOP 模組,織入器將該程式碼注入到 OOP 原始碼中,作為編譯程式碼的初步步驟。

至此,看起來 AOP 不過是一種從類中提取實用程式程式碼並將其集中起來的方法;這是 AOP 的優點之一。但是,AOP 可以分離更復雜的關注點。在我們的發票示例中,我們提到發票有一個逾期日期。同樣,我們自己的應付賬款也可能有一個逾期日期。這個“逾期”的關注點可以封裝為一個切面,該切面定義了對發票和應付賬款物件構造或初始化的切入點。在這些連線點上,可以向這兩個類新增一個逾期日期成員,以及程式碼以將發票/應付賬款註冊到一個逾期監控系統,該系統生成一個即將到期的每日報告。跟蹤付款期限的程式碼已移動到單個模組,減少了發票/應付賬款物件的複雜性,消除了發票/應付賬款類與期限監控系統之間的依賴關係,並使系統維護和更改變得更容易。

目前,AOP 最流行的平臺是 AspectJ,它是 Java 語言的擴充套件。在本示例中,將使用該語言。

華夏公益教科書