[半翻] 設計面向DDD的微服務

這篇文章行文結構對照微軟博客, 結合本人意譯和多年實踐的回顧思考形成此次讀書筆記。

Domian-driven Design

領域-驅動-設計(DDD)提倡基於(用例相關的現實業務)進行建模

1. DDD的視角

  • DDD將現實問題視爲領域;
  • DDD將獨立的問題描述爲有界限的上下文(一個有界上下文對應一個微服務),並強調通用語言討論這些問題

2. DDD提出的概念

許多技術概念和模式,例如充血模型(對應我們常寫貧血模型)、值對象、聚合和聚合根規則。

3. 目前實施DDD的現狀

有時DDD技術規則和模式被視爲障礙/囉嗦,對於實施DDD方法而言,學習曲線比較陡峭。
不要爲了實施而實施,最重要的是使用通用語言編寫與業務問題一致的領域代碼

此外僅當您要實現具有複雜業務規則的微服務時,才應使用DDD方法,諸如CRUD服務之類的簡單職責可以通過更簡單的方法進行管理。

DDD模式可以協助劃分微服務邊界
在已經確定的界限上下文,您可以爲領域建模:實體模型、值對象和聚合,DDD與邊界有關,微服務也與邊界有關。

儘量保持小型微服務

劃分界限上下文,要平衡兩個目標:

  1. 創建儘可能小的微服務(這一點不應該成爲主要動力)
  2. 要避免微服務之間過密的通信

這兩個目標可能彼此矛盾,兩者通過演進的方式達到平衡:
儘可能分解系統,直到在下次分解時感到服務通信迅速增加。

DDD微服務中的層

  1. DDD定義的多層是爲了管控代碼的複雜性, 這些層是邏輯組件(類似環環相扣的齒輪)。
  2. 不同的層(例如領域模型層與表示層等)可能具有不同的類型,此時層加類型需要轉換。

例如從數據庫中加載的實體,有時候需要做一下修正(截取部分信息、增加信息)才能適配客戶端UI。

  1. 領域模型層中的領域實體不應傳播到它不屬於的其他區域(如表示層)
  2. 重要的是有一個由聚合根控制的域模型,以確保與該實體組(聚合)相關的所有不變式和規則都是通過單個入口點或(聚合根)執行。

訂單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實體類可以實現軟件的核心,並且與基礎設施技術完全脫鉤。

總結

  1. 在DDD中,應用層依賴於領域和基礎設施層,而基礎設施依賴於領域層,但是領域層不依賴於任何層。
  2. 只在領域層編寫業務規則和通用的領域知識,而應用層負責針對軟件的目標來組合、協調領域層的業務規則。
  3. 領域層的領域實體、值類型、聚合根反映了真實業務的核心,需要用一種通用的語言來定義,這樣不管應用層多麼複雜,核心領域層自巋然不動。
  4. 領域層不能直接依賴與基礎設施層,現代ORM框架一般都提出倉儲模型來幫助領域層和技術設施層解耦。

翻譯自: https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/ddd-oriented-microservice

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章