MASA Framework - DDD 設計(1)
DDD
領域驅動設計是一個有關軟件開發的方法論
,它提出基於領域開發的開發模式,基於 DDD 理論,我們可以設計出高質量的軟件模型。
它圍繞業務概念構建領域模型來控制業務的複雜度,解決軟件難以理解和演化的問題。
微服務
微服務是一種架構風格
,通過進程間通訊、容錯和故障隔離等方式,實現去中心化的服務治理。
DDD 與微服務
它們都是高內聚、低耦合,從業務視角分離複雜度,提高響應能力。
高內聚:把相關的業務聚集在一起
低耦合:把關聯性較低的拆分爲獨立的服務
使用 DDD 搭建微服務我們將獲得以下優勢:
-
設計清晰,規範
-
基於領域模型,有利於領域知識的傳遞和傳承
-
幫助團隊建立良好的溝通
-
協助系統架構的演進
-
提高團隊的設計能力(面向對象,架構)
設計
領域設計涉及技術與業務,如何讓它們協作起來呢?
戰略設計(業務)
領域、子域、限界上下文
-
將領域拆分成子域,並劃分核心子域、支撐子域和通用子域
-
以子域展開事件風暴,根據上下文語義劃分限界上下文,建立通用語言,完成領域建模
-
領域建模將作爲能力中心規劃的重要依據
-
完成能力中心地圖和優先級後,作爲微服務設計的輸入完成戰術設計
戰術設計 (技術)
聚合、聚合根、實體、值對象、領域服務等
-
按照領域模型完成微服務設計和落地
-
建立聚合、聚合根、實體、值對象、領域服務等對象之間的依賴關係,以代碼對象的形式映射到服務中,採用分層架構完成微服務設計和落地
分層架構可以採用 Clean Architecture
DDD 實踐過程
我們將通過 DDD + Clean Architecture 完成業務與技術的完整落地
統一語言(戰略設計)
統一:
-
領域模型術語
-
DDD 模式名稱
技術:
-
技術設計術語
-
技術術語
-
技術設計模式
業務:
-
領域模型術語
-
DDD 模式名稱
-
業務術語
-
設計無關的業務術語
事件風暴(戰略設計)
Event Storming 是一種領域建模的實踐,可以讓領域相關人員快速理解業務模型
完整流程包括如統一語言、提出領域事件、規則、命令、讀模型、角色、劃分子域、票選、補充商機與價值等,
接下來我們先精簡一點步驟
活動準備
人:業務人員,領域專家,技術人員,架構師,測試等
看板:可以將事件流可視化的白板或者畫圖工具等
彩色貼紙:填寫事件,命令等
業務場景
規定業務場景,下面我以一個電商項目爲例
事件風暴結果
命令風暴結果
尋找聚合
聚合:一組相關領域模型的集合,儘量保證封裝業務的不變性,確保關聯關係緊密的領域模型內聚
- 按事件順序依次分析三個問題
-
事件改變的領域模型是什麼
-
領域模型是否可以獨立訪問,是就是聚合
-
不能獨立訪問,需要通過哪個領域模型(聚合)來訪問,將其放到對應聚合內
-
命令貼在聚合左邊代表輸入,事件貼到聚合右邊代表輸出
-
檢驗是否符合聚合規則,不匹配的重新調整聚合
聚合結果
尋找聚合過程中可能會因爲業務銜接產生新的輸入命令,以虛線表示
劃分限界上下文
限界上下文:某個場景或環境下的業務邊界
-
基於聚合和領域模型,判斷它們要解決的業務問題,如果是同一個問題則放到一個限界上下文中,否則就拆分
-
如果一個聚合同時解決多個問題,則需要對聚合進行拆分,將拆分後的聚合劃分到不同的限界上下文
-
解決的業務問題大小(變化原因,內在邏輯等)需與領域專家共同完成
限界上下文結果
界限上下文映射
當上下文很多的時候,不同的團隊負責不同的上下文,爲了保證有效的工作可以定義不同的上下文之間的關係來創建一個所有模型上下文的全局視圖。兩個上下文之間是有方向的,上游 (U 或 Upstream),下游 (D 或 Downstream)
界限上下文映射結果
子域
一個業務領域或子域是一個業務範圍。一個業務領域或子域可以包括多個業務能力,一個業務能力對應一個服務。
核心子域指業務成功的主要促成因素,是企業的核心競爭力。
通用子域被整個業務系統使用。
支撐子域是完成業務的必要能力,但不是成功的因素。
除了上面限界上下文結果中標註的子域外,還可以擴展出財務,市場,採購等子域
領域對象關係(戰術設計)
分解聚合,提取該聚合包含的領域對象
-
領域對象的業務不變性
-
領域對象具有一致的生命週期
定義實體與值對象(戰術設計)
實體:存在唯一性標識,實體間是否相等的判斷依據也是唯一標識
值對象:表示屬性的不變值
以訂單聚合爲例:
-
訂單聚合包含訂單實體,訂單行實體
-
訂單實體包含收貨地址值對象
Clean Architecture
尋找聚合時我們提到過輸入和輸出。而 Clean Architecture 與 DDD 集合後就非常適合作爲採用 DDD 方法論的架構落地指導
爲了更好的落地讀模型設計(查詢業務比較往往佔八成以上),搭配 CQRS 可能是個不錯的選擇。
CQRS 優勢在於職責分離,提高系統性能、可擴展性、安全性等。也可以從數據驅動轉爲事件驅動。
要了解 CQRS 可以看第二篇 MASA Framework - EventBus 設計
示例可以參考 MASA EShop 源碼:https://github.com/masalabs/MASA.EShop
除了 DDD 以外,我們還提供了 EventBus、Dapr、CQRS 等多種實現方式
老系統演進
絞殺者模式
在現有系統外圍將新功能用新的方式構建爲新的服務的策略,通過將新功能做成微服務方式,而不是直接修改原有系統,逐步的實現對老系統替換。採用這種策略,隨着時間的推移,新的服務就會逐漸 “絞殺” 老的系統。對於那些規模很大而又難以對現有架構進行修改的遺留系統,推薦採用絞殺者模式。
缺點:可能需要一段時間同時維護兩個或以上的項目
修繕模式
修繕者模式就如修房或修路一樣,將老舊待修繕的部分進行隔離,用新的方式對其進行單獨修復。修復的同時,需保證與其他部分仍能協同功能。從這種思路出發,修繕者模式更多表現爲一種重構技術。
DDD 實踐流程
總結
DDD 雖然需要一定的學習成本,但掌握後既可以設計複雜的工程,也可以適當的縮減流程,在小型項目中直接以領域和聚合快速抽象領域模型,配合自己習慣的技術手段(如論是 DB First 還是 Code First)來加強對系統設計的掌控力。
第一篇主要講解 DDD 在團隊中如何落地,而第二篇則是站在開發的角度如何落地。
學以致用,學無止境。
參考:
AWS 領域驅動設計最佳實踐
開源地址
MASA.BuildingBlocks:https://github.com/masastack/MASA.BuildingBlocks
MASA.Contrib:https://github.com/masastack/MASA.Contrib
MASA.Utils:https://github.com/masastack/MASA.Utils
MASA.EShop:https://github.com/masalabs/MASA.EShop
MASA.Blazor:https://github.com/BlazorComponent/MASA.Blazor
如果你對我們的 MASA Framework 感興趣,無論是代碼貢獻、使用、提 Issue,歡迎聯繫我們
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/mruuXzdqER9o15aDxfnigA