都知道物件導向了,那麼面向切面呢!通俗易懂帶你走進面向切面程式設計!

2020-08-12 20:28:25

什麼是AOP

1、概念

在軟體業,AOP爲Aspect Oriented Programming的縮寫,意爲:面向切面程式設計,通過預編譯方式和執行期間動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數語言程式設計的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。

說一下OOP

有一天面試官問你什麼是OOP?

然後你可能會一臉懵逼的說OOP?what?這是什麼玩意!其實它就是你一直學的物件導向程式設計(Object Oriented Programming),

那麼我們要怎麼理解物件導向程式設計呢?

我們都知道物件導向程式設計之前還有一個程序導向程式設計。我們學習程式設計的基礎C語言就是程序導向的程式設計。要怎麼具體理解這兩者的區別呢?

舉個簡單的例子。當你要吃一份蛋炒飯的時候,你該怎麼辦,下面 下麪給你兩個選擇!

1、 自己買食材,然後煮飯,炒蛋,加上一切你想下的配料然後最後炒完出鍋。

2、你去某某某大酒店,坐下大喊:「服務員!來一份蛋炒飯」(應該不會被打死吧,就點一份蛋炒飯)

看出來區別了嘛!其實說到這裏應該都有感覺了,1就是程序導向的,2就是物件導向的!

那麼這兩種程式設計方式到底有什麼區別呢?

第二種的話,你不需要知道蛋炒飯具體是怎麼做的,你只需要點餐然後最後就能吃到。如果你點完突然不想吃了(在服務員沒炒之前哈,不然老闆可能以爲你搞事情,會把你轟出去!),想換成牛肉炒飯,此時你只需要跟老闆說一聲就能換了。然後如果你本身是第一種的話,你剛買的食材就廢了。因爲你只有雞蛋,沒有牛肉,可能一切就得重新來過!這就兩者最明顯的區別

程序導向是一步一步分析,一步一步實現的,

物件導向是模型化的,我們只需要抽象出一個類就行,封裝起來,然後要用的時候直接呼叫。至於具體裏面怎麼實現的(就是蛋炒飯怎麼抄的完全不關我們的事情,我們只需要吃就行了!)

所以現在來總結一下兩者的優缺點:

物件導向:

  • 優點:易維護、易複用、易擴充套件
  • 缺點:效能比較差,因爲類呼叫時需要範例化,開銷比較大,比較消耗資源

程序導向:

  • 優點:效能好
  • 缺點:不易維護、不易複用、不易擴充套件

然後下面 下麪回到我們今天的主題,AOP面向切面程式設計!是在我們的 OOP的基礎上提出來的!

2、切面要怎麼理解?

AOP是面向切面程式設計,那麼這個切面到底是指什麼呢?

其實很容易理解,一個完整的西瓜,我們拿一把刀沿着中間切下去,此時我們就得到了兩個切面。

在程式設計中,物件與物件之間,方法與方法之間,模組與模組之間都是一個個切面

3、那麼面向切面有什麼用呢?

先來說一下我們很熟悉的一個例子:

例如:現在有一個 Dog類 和 Cat類,它們都有共同的方法,它們都能跑 run(),都能吃 eat()。

在我們 OOP中,此時就會寫一個 Animal類,這個類有了 Dog類和 Cat類中共同的方法。run() 和 eat()

這樣的話我們就只需要在實現 Dog和Cat 的時候,去繼承 Animal類即可!這樣確實減少了我們重複程式碼的書寫。

但是現在問題來了!

如果此時在我們的父類別中多個方法的相同位置中,出現了很多重複的程式碼!此時應該怎麼辦?還有的是,Java只提供單繼承,不能繼承其它父類別。

OOP 是一個縱向的的體系,從上到下的。

所以此時我們的主角來了!AOP 面向切面的。

把這一處處需要用到這些共同方法地方都看成一個切面,然後把共同方法獨立出來。再橫切進去。

可能有人會想說,我們父類別中,不就是把子類中共同的方法提出來了嘛?那麼這不是一樣的嗎?

但是我們還需要想到的一點就是,父類別中也會有自己的一些動作(自己的業務程式碼),此時和這些子類的共同方法混雜在了一起,這個時候就會顯色十分的臃腫!變得不易維護!

AOP就是用來解決這些問題的!

AOP 將我們這些所謂的需要橫切的程式碼單獨提取出來,和原來的業務程式碼進行了分離。

image-20200812153600925

上面這張圖就能夠很明顯的看出來,這兩者的不同。在這個過程中,需要保證的是,原來的業務程式碼不能被破壞掉!

4、AOP 解決了什麼問題呢?

通過上面的分析可以發現,AOP 主要用來解決:在不改變原有業務邏輯的情況下,增強橫切邏輯程式碼,根本上解耦合,避免橫切邏輯程式碼重複。

5、AOP 中的相關概念

學習了Spring的同學可能就知道,在Spring中,有兩個很重要的東西,一個是 IOC , 另外一個就是AOP了,IOC在我的上一篇文章就已經帶着大家理解了一遍了,沒看的同學們可以檢視歷史訊息。在Spring中,AOP有很多專業的概念,以下爲大家列了出來:

  • Aspect(切面): Aspect 宣告類似於 Java 中的類宣告,在 Aspect 中會包含着一些 Pointcut 以及相應的 Advice。
  • Joint point(連線點):表示在程式中明確定義的點,典型的包括方法呼叫,對類成員的存取以及例外處理程式塊的執行等等,它自身還可以巢狀其它 joint point。
  • Pointcut(切點):表示一組 joint point,這些 joint point 或是通過邏輯關係組合起來,或是通過通配、正則表達式等方式集中起來,它定義了相應的 Advice 將要發生的地方。
  • Advice(增強):Advice 定義了在 Pointcut 裏面定義的程式點具體要做的操作,它通過 before、after 和 around 來區別是在每個 joint point 之前、之後還是代替執行的程式碼。
  • Target(目標物件):織入 Advice 的目標物件.。
  • Weaving(織入):將 Aspect 和其他物件連線起來, 並建立 Advice的 object 的過程

然後最後舉一個例子,例子是在CSDN上面看到的,非常的形象!文字有點多,但是還是希望大家把它看完,看完後真的受益匪淺

讓我們來假設一下, 從前有一個叫爪哇的小縣城, 在一個月黑風高的晚上, 這個縣城中發生了命案. 作案的兇手十分狡猾, 現場沒有留下什麼有價值的線索. 不過萬幸的是, 剛從隔壁回來的老王恰好在這時候無意中發現了兇手行兇的過程, 但是由於天色已晚, 加上兇手蒙着面, 老王並沒有看清兇手的面目, 只知道兇手是個男性, 身高約七尺五寸. 爪哇縣的縣令根據老王的描述, 對守門的士兵下命令說: 凡是發現有身高七尺五寸的男性, 都要抓過來審問. 士兵當然不敢違背縣令的命令, 只好把進出城的所有符合條件的人都抓了起來.

小故事和 AOP 到底有什麼對應關係?

首先我們知道, 在 Spring AOP 中 Joint point 指代的是所有方法的執行點, 而 point cut 是一個描述資訊, 它修飾的是 Joint point, 通過 point cut, 我們就可以確定哪些 Joint point 可以被織入 Advice. 對應到我們在上面舉的例子, 我們可以做一個簡單的類比, Joint point 就相當於 爪哇的小縣城裏的百姓,pointcut 就相當於 老王所做的指控, 即兇手是個男性, 身高約七尺五寸, Advice 則是施加在符合老王所描述的嫌疑人的動作: 抓過來審問.
爲什麼可以這樣類比呢?

  • Joint point : 爪哇的小縣城裏的百姓: 因爲根據定義, Joint point 是所有可能被織入 Advice 的候選的點, 在 Spring AOP中, 則可以認爲所有方法執行點都是 Joint point. 而在我們上面的例子中, 命案發生在小縣城中, 按理說在此縣城中的所有人都有可能是嫌疑人.
  • Pointcut :男性, 身高約七尺五寸: 我們知道, 所有的方法(joint point) 都可以織入 Advice, 但是我們並不希望在所有方法上都織入 Advice, 而 Pointcut 的作用就是提供一組規則來匹配joinpoint, 給滿足規則的 joinpoint 新增 Advice. 同理, 對於縣令來說, 他再昏庸, 也知道不能把縣城中的所有百姓都抓起來審問, 而是根據兇手是個男性, 身高約七尺五寸, 把符合條件的人抓起來. 在這裏 兇手是個男性, 身高約七尺五寸 就是一個修飾謂語, 它限定了兇手的範圍, 滿足此修飾規則的百姓都是嫌疑人, 都需要抓起來審問.
  • Advice :抓過來審問, Advice 是一個動作, 即一段 Java 程式碼, 這段 Java 程式碼是作用於 point cut 所限定的那些 Joint point 上的. 同理, 對比到我們的例子中, 抓過來審問 這個動作就是對作用於那些滿足 男性, 身高約七尺五寸 的爪哇的小縣城裏的百姓.
  • Aspect::Aspect 是 point cut 與 Advice 的組合, 因此在這裏我們就可以類比: 「根據老王的線索, 凡是發現有身高七尺五寸的男性, 都要抓過來審問」 這一整個動作可以被認爲是一個 Aspect.

所以這個小故事其實很好的向我們展示了彼此之間的關係!

能夠看到這裏的同學,我覺得毅力是相當的好的!因爲這篇文章基本全身理論性的東西,阿藍在書寫和規劃的過程也是有想到寫出來會十分的枯燥!但是沒辦法,我們看完了能夠掌握到它的精髓,這就很足夠了!

最後補充一下AOP的應用場景

Authentication 許可權

Caching 快取

Context passing 內容傳遞

Error handling 錯誤處理

Lazy loading 懶載入

Debugging  偵錯

logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準

Performance optimization 效能優化

Persistence  持久化

Resource pooling 資源池

Synchronization 同步

Transactions 事務

END

最後希望這篇文章能夠幫助到你,如果文章中存在什麼錯誤,請大家加以指正!