Posted on

XSpect簡介(一個AOP觀念實作的框架)

講者資料:小
投影片:XSpect
專案github位置:在此

這是10/17在cocoaHead聚會裡由講者所分享的一個他自己所寫的framework
因為他是在今日議程的最後一個講者,有些部份講的較為快速、簡短
有很多投影片也跳過去未說,在當下聽時只能大略聽到一個概念。

較引起我注意的地方,是他所提到的AOP的觀念與應用
也因為對他所說的AOP的觀念以及相關應對、程式設計方式感到蠻有趣的
這部份在會議結束後也花蠻多時間在研究該講者的code以及相關概念的研究

這是講者對AOP的解釋:

如果我要敘述 AOP 在幹嘛,或是說他的目的的話。我會說 AOP 是在用另一種方式去封裝變化,達到原本 OOP 做不到的事。這個變化就是 crosscutting concerns。
crosscutting concerns 就是為了一個邏輯,而散布在四處的程式碼。
AOP 就是要把他們全部包裝在一起。

下面的是其他網頁對於AOP的解釋

AOP全名Aspect-Oriented Programming,我們先來看看XXX-Oriented的意義,通常翻譯「XXX導向」,也就是以XXX為中心,例如中文中「客戶導向」就是以客 戶為中心,而「物件導向」(OOP:Object-Oriented Programming)就是以物件為中心的程式設計。

自然的,Aspect-Oriented Programming,就是「Aspect導向程式設計」,也就是以Aspect為中心的程式設計,但什麼是Aspect?中文直譯通常是「方面」,但這個名詞容易使人混淆。

牛津字典中的英英解釋對Aspect是:particular part or feature of sth being considerd.

所以Aspect在英文中不只有「方面」的意思,還有部份(part)的意思。中文中稱「就這個方面來說」,通常指的是「就這個角度來說」或 「就這個方向來說」,這個解釋不適用於AOP中的Aspect。如果英文中說from this aspect of sth,除了可以翻譯為上面兩句的意義之外,還可以翻作「就這個部份來說」。

以我們的前一個主題中的記錄(log)動作插入至HelloSpeaker物件的hello()中為例,我們說「就記錄這個部份」是不屬於 HelloSpeaker職責的,它被硬生生切入HelloSpeaker中,英文中我們可以說:The logging aspect of the “hello” method doesn’t belong to the job of HelloSpeaker.

所以以整個方法的執行流程來說,如果執行流程是縱向的,則記錄這個動作硬生生的「橫切」入其中,這個橫切入的部份我們就稱之為Aspect,它 是橫切關注點(crosscutting concern,一個concern可以像是權限檢查、事務等等)的模組化,將那些散落在物件中各處的程式碼聚集起來。

所以Aspect要用中文表達的話,適切一些的名詞該是「橫切面」或「切面」。AOP關注於Aspect,將這些Aspect視作中心進行設 計,使其中從職責被混淆的物件中分離出來,除了使原物件的職責更清楚之外,被分離出來的Aspect也可以設計的通用化,可運用於不同的場合。

然後這個是XSpect框架的架構圖
2013-10-28_135639

簡單來說,使用AOP的框架主要是為了把 crosscutting concerns 封裝在一起,提高程式模組化的程度。
以上圖來看,左邊的部份是原本的程式寫法,假如是一個儲存資料的函數如下,以原本的寫法來看,或許檢查值是否符合格式這部份的程式碼,在許多地方都可以用到,AOP主要便是去關心多個相似的流程的衡切面裡共通的部份,橫著去”跨越”多個程序裡使用的相同的功能。

log是一個標準的crosscutting concern範例,因為log的策略會牽動整個系統的每一個必需記錄的部份。
從橫向去記錄和登記所有classes和methods。

假如今天我們一個送交表單的程式碼,長的像是這樣:

function saveForm(){
...檢查欄位是否為空。
...檢查輸入的值是否符合格式。
[真正的儲存工作]
...後續相關操作(存LOG、紀錄操作等...)
...顯示儲存結果

}

我們可以看到,在這個函數裡面,只有[真正的儲存工作]是函數真正要做的事情,
剩的部份都是要處理商業需求的商業邏輯而寫的功能。這樣的程式碼撰寫方式,會造成寫出的程式只能專門用在單一工作,降低程式碼的重用性以及可維護性。

例如我們今天在程式的多個地方都需要使用LOG來紀錄所有的商務操作,
若今天這一項業務邏輯需要做修改或是移除,
那麼整個專案裡有加入這個LOG功能的部份,都需要同時去更新,這將會增加整個維護的成本。

因此,這個AOP的框架就是為了要將這些和業務相關的程式碼與原本的程式碼分開,
(商務邏輯,稱為Aspect,具體實作這些商務邏輯的程式碼則稱為Advice)
利用程式切入點Joinpoint(在應用程式執行時加入商務流程的點或時機稱之為Joinpoint),
並設定那些Aspect要用在那些Joinpoint裡,這個設定的定義稱為PointCut。

這邊的文章有AOP相關專有名詞的解釋:AOP觀念與術語,下圖則是講者大大的相關說明圖
2013-10-28_143641

這個框架可以讓商業邏輯獨立出物件之外,只需要設定Joinpoint便可以將之插入程式邏輯中。
如果對這個講者個框架有興趣的話,可至他的GITHUB上有更完整的使用手冊及範例: XSpect Tutorial

PS: 在當場講解時,有在場的大大提供了另一個很完整、並且功能與這一套框架相似的框架
叫作ReactiveCocoa,若對AOP有興趣者,也可以到這個網站去看看另一種方式的實作
https://github.com/ReactiveCocoa/ReactiveCocoa

 

相關資料

  1. XSpect, a lightweight library to make your code reusable and maintainable
  2. XSpect Tutorial
  3. AOP入門
  4. AOP觀念與術語