規約
建立規範類
使用倉儲規約
組合規約
討論介紹
規約模式是一種特別的軟體設計模式,通過使用布林邏輯將業務規則鏈結起來重新調配業務規則。(維基百科)。
尤其是,它通常用來為實體或其他業務物件定義可復用的過濾器。
示例
在這個部分,我們將看到規約模式的必要性。本部分是通用的,和abp的實現沒有必然的關係。
假定,有乙個服務方法,計算所有客戶的總數量,如下所示:
public你或許希望通過過濾器獲取客戶數量。例如,你有優質客戶(擁有超過100,000美元的客戶)或者想通過註冊年份過濾客戶。然後你建立了其他方法,如getpremiumcustomercount(),class customermanager
}
getcustomercountregisteredyear(int year),getpremiumcustomercountregisteredinyeaar(int year)還有更多。隨著你有更多的標準,不可能為每種可能都建立乙個組合。
這個問題的解決方案之一就是規約模式。我們建立乙個單獨的方法,它有乙個引數,我們把這個方法作為過濾器:
public從而,我們可以使用實現了ispecification介面的引數來獲取任何物件,介面定義如下所示:class customermanager
public
int getcustomercount(ispecification
spec)
}return customercount;}}
public我們可以呼叫issatisfiedby方法來測試客戶是否是有意向的。從而,我們可以使用不同的引數呼叫同樣的方法getcustomercount,而不用改變方法本身。inte***ce ispecification
因為這個解決方案在理論上相當好,所以在c#中它應該被改善的更好。例如,從資料庫裡獲取所有的客戶並檢查他們是否滿足指定的規約/條件,這個操作是非常低效的。在下一部分,我們將看到abp如何實現這個模式並克服了這個問題。
建立規範類
abp按如下方式 定義了ispecification介面:
public新增了toexpression()方法,這個方法返回乙個表示式,這樣可以 更好的和iqueryable和表示式樹整合。因此,我們可以輕鬆的傳遞規約到倉儲,並在資料庫級別應用過濾器。inte***ce ispecification
我們通常繼承specification類,而不是直接實現ispecification介面。specification類自動實現issatisfiedby方法。所以,我們僅僅需要定義toexpression。讓我們建立一些規約類:
//如你所見,我們僅僅實現了簡單的拉姆達表示式來定義規約。讓我們使用這些規約獲取客戶的數量:customers with $100,000+ balance are assumed as premium customers.
public
class premiumcustomerspecification : specification}//
a parametric specification example.
public
class customerregistrationyearspecification : specification
public customerregistrationyearspecification(int year)
public
override expressionbool>> toexpression()
}
count = customermanager.getcustomercount(new premiumcustomerspecification());使用倉儲規約count = customermanager.getcustomercount(new customerregistrationyearspecification(2017));
現在,我們優化customermanager在資料庫中應用過濾器:
public這是非常簡單的。我們可以傳遞任何規約到倉儲,因為倉儲可以使用表示式作為過濾器。在這個例子中,customermanager是不需要的,因為我們可以直接在倉儲裡使用規約查詢資料庫。但是,我們想在一些客戶上執行業務操作,在這種情況下,我們可以在領域服務裡使用規約指定需要操作的客戶。class customermanager
public
int getcustomercount(ispecificationspec)
}
組合規約
規約乙個強大的特徵是可以使用and,or,not和andnot擴充套件方法進行組合使用。示例:
var count = customermanager.getcustomercount(new premiumcustomerspecification().and(new customerregistrationyearspecification(2017)));我們甚至可以基於已有的規約建立乙個新的規約:
publicandspecification是specification類的乙個子類,這個類只有兩個規約都滿足時才滿足。因此我們可以像其他規約那樣使用newpremiumcustomersspecification:class newpremiumcustomersspecification : andspecification
}
var count = customermanager.getcustomercount(new newpremiumcustomersspecification());討論
因為規約模式比c#拉姆達表示式久遠,它經常和表示式比較。一些開發者可能認為不再需要規約模式,我們可以直接傳遞表示式給倉儲或領域服務,如下:
var count = _customerrepository.count(c => c.balance >因為abp倉儲支援表示式,所以這種使用方式完全有效。你不需要在應用裡定義或使用任何規約,你可以繼續使用表示式。所以,規約的點是什麼?為什麼還有什麼時候我們該考慮使用它呢?100000
&& c.creationyear == 2017);
什麼時候使用?
使用規約的一些好處:
什麼時候不使用?
返回主目錄
ABP官方文件翻譯 3 4 領域服務
領域服務 一些 介紹 領域服務 或者在ddd中單純的服務 用來執行領域操作和業務規則。eric evans在他的ddd書中描述了乙個好的服務有三個特徵 1.與領域概念關聯的操作,但不是實體或值物件的自然組成部分。2.介面的定義依照領域模型的其他元素。3.操作是無狀態的。不像應用服務那樣獲取或返回dt...
ABP官方文件翻譯 3 2 值物件
值物件 介紹 展現領域描述性層面且沒有概念性身份的物件稱之為值物件。eric evans 和實體相反,實體有身份標示 id 值物件沒有身份標示。如果兩個實體的身份標示是不同的,那麼就認為他們是不同的物件 實體,即使他們的所有屬性都是一樣的。考慮兩個不同的人有相同的名字 姓氏和年齡,但是他們是不同的人...
ABP文件翻譯 值物件
本人是abp初學者,在看英文文件和 tkb至簡 的abp框架理論研究總結 典藏版 時,發現大神 tkb至簡中少了對value objects的翻譯,看文件是新的,大神沒時間把,小弟給補充上。用於描述領域的某個方面而本身沒有概念標識的物件稱為 a value object eric evans 對於實...