面向方面編程簡介

言鼎科技 2023-05-04 359
面向方面編程簡介

目錄

1. 面向切面編程的定義

2. 用Javascript應(yīng)用AOP

3.  AOP核心概念詳解

4. 關(guān)于 AOP 的幾點(diǎn)思考

面向方面的編程定義

在計算中,面向方面編程(AOP)是一種編程范式,旨在通過允許分離橫切關(guān)注點(diǎn)來增加模塊化。

交叉問題是影響其他問題的程序的各個方面。在設(shè)計和實(shí)現(xiàn)中,這些問題通常無法從系統(tǒng)的其余部分清楚地分解出來,并且可能導(dǎo)致分散(代碼重復(fù))、混亂(系統(tǒng)之間的顯著依賴性)。

往往是交叉問題的例子包括:

  • 緩存

  • 數(shù)據(jù)驗(yàn)證

  • 記錄

  • 格式化數(shù)據(jù)

  • 事務(wù)處理

  • ……

以這個場景為例:

您開發(fā)了一個具有大量getter 方法的服務(wù),以從數(shù)據(jù)庫中獲取數(shù)據(jù)并將結(jié)果格式化為 JSON 字符串。

服務(wù)類{   getUser ({id, name}) {
   如果 (!Number.isInteger(id))
     返回空
   const user = DAO.fetch(User, id, name)    返回 JSON.stringify(user)
 }
 獲取文章({id}){
   如果 (!Number.isInteger(id))
     返回空
   const article = DAO.fetch(文章, id)
   返回 JSON.stringify(文章)
 }
 // 獲取 Xyz ...}

數(shù)據(jù)訪問對象(DAO) 可以簡化為:

const DAO = {
 // 數(shù)據(jù)庫訪問,在這里查詢和檢索結(jié)果
 獲?。P?,...參數(shù)){
   返回新模型(...參數(shù))
 }}

這是您的模型:

類文章{
 構(gòu)造函數(shù)(id){
   這個.id = id
 }}類用戶{
 構(gòu)造函數(shù)(id,名稱){
   這個.id = id
   this.name = 名稱
 }}

如您所見,Service的任何getter 方法都可以分為 3 個部分(或 3 個關(guān)注點(diǎn)): 

  • 數(shù)據(jù)驗(yàn)證:檢查id 是否為整數(shù)。

  • 主要關(guān)注:與數(shù)據(jù)訪問層通信。

  • 格式化數(shù)據(jù):將結(jié)果轉(zhuǎn)換為 JSON 字符串。

在這個例子中,這 3 個問題被過度簡化了。但在實(shí)際應(yīng)用程序中,主要關(guān)注點(diǎn)、數(shù)據(jù)驗(yàn)證格式數(shù)據(jù)邏輯可能會變得非常復(fù)雜。

數(shù)據(jù)驗(yàn)證格式數(shù)據(jù)邏輯是橫切關(guān)注點(diǎn),應(yīng)該與主要關(guān)注點(diǎn)隔離開來,因?yàn)樗鼈儠稚㈤_發(fā)人員對主要業(yè)務(wù)邏輯的注意力。

因此,我們應(yīng)該將它們分開并放在三個不同的地方:

  • 服務(wù)模塊應(yīng)該處理主要關(guān)注點(diǎn),或者核心業(yè)務(wù)邏輯。

  • 數(shù)據(jù)驗(yàn)證模塊應(yīng)該負(fù)責(zé)驗(yàn)證數(shù)據(jù)。

  • 格式化數(shù)據(jù)模塊應(yīng)該負(fù)責(zé)格式化數(shù)據(jù)。

使用 Javascript 應(yīng)用 AOP

 

有許多庫和框架允許我們實(shí)現(xiàn) AOP 解決方案來應(yīng)對橫切關(guān)注點(diǎn)。

在這里,我們使用 Javascript 庫:方面.js

 

 

從主要關(guān)注點(diǎn)中刪除所有橫切關(guān)注點(diǎn),我們重寫服務(wù) 模塊如下:

從 'aspect.js' @Advised ()導(dǎo)入 { Advised }類服務(wù){(diào)
 getUser({id, name}) {
   返回 DAO.fetch(用戶,ID,名稱)
 }
 getArticle({id}) {
   返回 DAO.fetch(文章,id)
 }}

 

@Advised裝飾器 有助于將ValidateAspect FormatAspect 連接到服務(wù) 類中。Service的實(shí)現(xiàn) 非常簡潔易讀。它只專注于它的主要職責(zé)。

最后,我們可以嘗試調(diào)用一些方法來查看結(jié)果:

const service = new Service()控制臺。日志(service.getArticle({id: '1'}))// 空控制臺。日志(service.getUser({id: 2, name: 'Hello Kitty'}))// {"id":2,"name":"Hello Kitty"}

 AOP 的核心概念解釋

1/ 看點(diǎn)

方面是具有一組橫切功能的模塊

例如:ValidateAspect,FormatAspect 

為了形成切面,我們定義了切入點(diǎn)建議

2/ 加入點(diǎn)

連接點(diǎn)是應(yīng)用程序中我們可以插入 AOP切面的特定點(diǎn)。比如方法執(zhí)行、異常處理、變量修改……很多時候,一個連接點(diǎn)代表一個方法執(zhí)行。

3/ 建議

建議是在特定連接點(diǎn)采取行動。換句話說,它是在連接點(diǎn)之前或之后執(zhí)行的實(shí)際代碼。

例如:@beforeMethod、@afterMethod、  @aroundMethod

4/ 切入點(diǎn)

切入點(diǎn)是與連接點(diǎn)匹配以確定是否需要運(yùn)行建議的謂詞。根據(jù)庫或框架,可以使用模式或表達(dá)式以不同方式指定切入點(diǎn)。

與圖書館方面.js本文中使用的切入點(diǎn)是用 Javascript 正則表達(dá)式 (Regex) 指定的:

{
   類名模式:/.*/,    
   方法名稱模式:/^(get)/  }

5/ 目標(biāo)對象

目標(biāo)對象是由一個或多個方面建議的對象。也稱為建議對象。

例如:示例中使用的服務(wù)類。 

6/ 編織

編織是將方面與其他對象鏈接起來以創(chuàng)建建議對象的過程。

例如:使用@Advised裝飾器在服務(wù)類上應(yīng)用編織。  

關(guān)于 AOP 的幾點(diǎn)思考

好處

  • 擁抱模塊化。

  • 減少依賴之間的耦合。

  • 使代碼更易于閱讀、重用和維護(hù)。

缺點(diǎn)

  • 不包含在編程語言中,必須依賴庫才能工作。

  • 調(diào)試可能很困難,因?yàn)榇a流遠(yuǎn)不止于此。

  • 要求紀(jì)律不要過度使用。

面向方面編程在 OOP 世界中被認(rèn)為是“黑暗藝術(shù)”,因?yàn)樗梢愿深A(yù)您的代碼并在幕后執(zhí)行一些黑魔法。例如,它可以修改您的方法、替換結(jié)果,甚至阻止您的代碼執(zhí)行。

盡管它提供了所有的功能,但我們應(yīng)該小心并深刻理解地使用 AOP。在您的應(yīng)用程序中不必要地使用 AOP 可能是有害的,并可能導(dǎo)致許多意外錯誤。

面向方面編程并不是面向?qū)ο缶幊痰?/span>絕對替代。相反,他們是同伴。

面向方面編程通過提供另一種思考程序結(jié)構(gòu)的方式來補(bǔ)充面向?qū)ο缶幊獭?/span>OOP 中模塊化的關(guān)鍵單元是類,而在 AOP 中模塊化的單元是方面

言鼎科技

The End