貧血模型 和 充血模型
前情提要,這是一題公司同仁提出的 QA問答,我希望透過分享我的觀點 以及 記錄的方式,能夠獲得更多的建議,或是在未來回顧時,能重新審視。
首先先讓我們了解 貧血 和 充血 模型各自會碰上什麼事情
貧血 也就是 資料 和 行為 拆開來了,意思是說我們的 邏輯是依附在使用案例上的,這樣會導致 削弱了內聚性,我們的實體或聚合 只是一組資料結構,它沒有辦法表達出 實際上對應的業務內容,傳達 業務知識 的能力相對 薄弱,除此之外這其實是違反物件導向的精神的,它其實是一種更偏向 面對過程 的開發,這也間接的導致你 失去對於資料的控制權,很難確保 資料的正確性和一致性。
充血 也就是 資料 和 行為 聚在一起,有強烈的內聚性,能夠表達 對應的業務內容,有較好的傳達業務知識能力,是一種典型的物件導向精神。不過相對的,不擅長應對複雜的業務場景,很容易產生超人類 (賦予太多權限) ,造成依賴關係產生強耦合,使得獨立性和可維護性下降。而 Application Service 層其實只是空空的一層 Facade。
意思是說 不論貧血或充血模型,都會有 其擅長與不擅長 的事情。 而其中如何折衷,如何評估邏輯該歸屬於哪一層級,則可以依據 Eric Evans 的 Domain Driven Design 一書中提到: 應用層,主要是在描述應用程序所要做的工作,並調度豐富的領域模型來完成它。這個層次的任務是描述業務邏輯,或和其它項目的應用層做交互。 這層很薄,不包含任何業務規則或知識,僅用於調度和派發任務給下一層的領域模型,這層沒有業務狀態,但可以爲用戶或程序提供任務狀態。
並依據 SRP 原則來看這件事情,一個模組應只對唯一的一個角色負責,因此應用層中的模組應該只負責調度和派發任務,而不應該包含任何業務邏輯或知識。
而最簡單的判別方式有
- 一個規則 是否 涉及多個實體(角色)?
- 規則是在描述 業務流程(角色) 還是 實體(角色) ?
- 規則是否會因為不同場景(角色) 而產生變化?
- 規則是否會因為不同的業務需求(角色) 而產生變化?
- 你想傳達的是領域知識 還是 使用敘述?