這篇文章行文結構對照微軟博客, 結合本人意譯和多年實踐的回顧思考形成此次讀書筆記。
Domian-driven Design
領域-驅動-設計(DDD)提倡基於(用例相關的現實業務)進行建模
。
1. DDD的視角
- DDD將
現實問題視為領域
; - DDD將
獨立的問題描述為有界限的上下文
(一個有界上下文對應一個微服務),並強調通用語言討論這些問題
2. DDD提出的概念
許多技術概念和模式,例如充血模型(對應我們常寫貧血模型)、值對象、聚合和聚合根規則。
3. 目前實施DDD的現狀
有時DDD技術規則和模式被視為障礙/啰嗦,對於實施DDD方法而言,學習曲線比較陡峭。
不要為了實施而實施,最重要的是使用通用語言編寫與業務問題一致的領域代碼。
此外僅當您要實現具有復雜業務規則的微服務時,才應使用DDD方法,諸如CRUD服務之類的簡單職責可以通過更簡單的方法進行管理。
DDD模式可以協助划分微服務邊界
在已經確定的界限上下文,您可以為領域建模:實體模型、值對象和聚合,DDD與邊界有關,微服務也與邊界有關。
盡量保持小型微服務
划分界限上下文,要平衡兩個目標:
- 創建盡可能小的微服務(這一點不應該成為主要動力)
- 要避免微服務之間過密的通信
這兩個目標可能彼此矛盾,兩者通過演進的方式達到平衡:
盡可能分解系統,直到在下次分解時感到服務通信迅速增加。
DDD微服務中的層
- DDD定義的多層是為了管控代碼的復雜性, 這些層是邏輯組件(類似環環相扣的齒輪)。
- 不同的層(例如領域模型層與表示層等)可能具有不同的類型,此時層加類型需要轉換。
例如從數據庫中加載的實體,有時候需要做一下修正(截取部分信息、增加信息)才能適配客戶端UI。
- 領域模型層中的領域實體不應傳播到它不屬於的其他區域(如表示層)
- 重要的是有一個由聚合根控制的域模型,以確保與該實體組(聚合)相關的所有不變式和規則都是通過單個入口點或(聚合根)執行。
訂單DDD微服務有三層:
- 應用程序層 Ordering.API
- 領域層 Ordering.Domain
- 基礎設施層 Ordering.Infrastructure
三層形成的類庫有清晰且明確的依賴關系
1. The domain model layer
負責表達業務概念、業務場景和業務規則。這一層會將技術細節傳遞到基礎設施層,這一層控制、反映業務場景,是業務軟件的核心。
-
領域模型層是表達業務的地方,在編程上體現為
捕獲數據和行為(具有邏輯方法)的領域實體的類庫
-
遵循
持久性無感知和基礎設施無感知
原則
領域模型層必須完全忽略數據持久性細節,這些持久性任務應由基礎設施層執行,因此,此層不應直接依賴基礎設施,這意味着一個重要規則是領域模型實體類應為POCO。
領域實體不應直接依賴於任何數據訪問基礎框架(EF、NHibernate),理想情況下,您的域實體不應繼承自或實現任何基礎設施中定義的任何類型。 大多數現代的ORM框架(例如Entity Framework Core)都支持這種方法,因此您的領域模型不會與基礎設施耦合。
- 領域模型中遵循
持久性無感知
原則很重要,但也不應忽略持久性問題
理解物理數據模型以及它如何映射到您的實體對象模型仍然非常重要,否則你的設計將會是空中樓閣。而且,大多數時候你將本應該采用關系數據庫的設計直接遷移到 NoSQL或面向文檔的數據庫,領域模型層很可能不適用(基於存儲技術和ORM技術,您的實體模型仍然必須遵守一些約束條件)。
2.Application Layer
定義軟件要執行的工作,並引導(可表達的領域對象)解決問題。
該層對對業務負責,有時會與其他系統的應用程序層交互。
該層保持薄
: 它不包含業務規則或知識,而僅協調任務並將工作委托給下一層的域對象協作;
它沒有反映業務情況的狀態,但是可以具有反映用戶或程序的任務進度的狀態。
微服務的應用層在.NET中一般表現為WebAPI,webapi實現交互、遠程網絡連接、為UI/Client app提供的外部請求中轉。
再次強調webapi不應該包含業務規則或領域知識(尤其是用於事務或更新的領域規則),這些應歸領域模型類庫所有。
應用層只能協調任務,不能保存或定義任何域狀態(域模型),它將業務規則的執行委托給領域模型類本身(聚合根和域實體),這將最終更新這些域實體中的數據。
總體來看,應用層是為實現前端用例的地方。
3. The infrastructure layer
基礎設施層: 定義如何將最初保存在領域實體中的數據持久化到數據庫或者其他存儲結構的過程。
一個示例是使用Entity Framework Core代碼實現存儲庫模式類: 該存儲庫模式類使用DBContext將數據持久存儲在關系數據庫中。
根據前面提到的持久化無感知
和基礎設施無感知
原則,基礎設施層不得“污染”領域模型層。
再次強調:必須保持領域層實體對基礎設施層框架的無感知狀態, 領域模型層類庫應該只包含領域代碼,而只有POCO實體類可以實現軟件的核心,並且與基礎設施技術完全脫鈎。
總結
- 在DDD中,應用層依賴於領域和基礎設施層,而基礎設施依賴於領域層,但是領域層不依賴於任何層。
- 只在領域層編寫業務規則和通用的領域知識,而應用層負責針對軟件的目標來組合、協調領域層的業務規則。
- 領域層的領域實體、值類型、聚合根反映了真實業務的核心,需要用一種通用的語言來定義,這樣不管應用層多么復雜,核心領域層自巋然不動。
- 領域層不能直接依賴與基礎設施層,現代ORM框架一般都提出倉儲模型來幫助領域層和技術設施層解耦。