一次關於聚合根的激烈討論
背景
因爲這是面向頁面建模,不是面向領域建模,將微服務拆分和領域建模混爲一談了
於是我以聚合根定義作爲引子,結合組內在實踐 DDD 過程中,聚合根隨着業務查詢複雜而導致聚合根不斷膨脹的問題,提出借鑑 CQRS 讀寫分離的理念,來解這個問題。 詳見 DDD-CQRS 能解聚合根的問題嗎引發了大家對領域模型的重新思考和激勵討論。歷經 3 小時得出了一些結論,達成了共識。
過程
通常我們說領域建模不應該去考慮微服務架構,工程結構,應該專注於業務。
但在實踐過程中發現這並不是一個好的方式,或者說是可落地的。因爲業務領域建模完成後,還是要反映到系統架構中,
最終是要落地到代碼實現,通過代碼來表達出領域模型。所以說我們的討論不應該是脫離
系統架構的。但是當我們發現業務領域建模完,通過代碼實踐一段時間後,發現代碼模型腐化了,這時候
我們首先思考的方向不應該是通過代碼來糾正,而是應該回歸到業務建模。
結論
聚合根
-
聚合根代表的是一個領域邊界
-
聚合根的內容要保證數據一致性(這裏的一致性指的不是數據持久化的事務一致性,而是業務數據的一致性,包含業務上的業務校驗) 比如訂單和訂單詳情,一個沒有訂單詳情的訂單是不完整的
-
聚合根裏面有多少個實體,由領域建模決定
-
永遠不要刪除聚合根
-
聚合根之間有引用,如果刪除了聚合根,會導致關聯聚合的數據不一致
這邊很容易和實體的生命週期從屬於聚合根搞混了。這邊的依賴是關聯依賴,實體依賴聚合根是 has a
-
聚合根引用聚合根值 id / 或者 id 值對象
實體
-
實體一般從屬於某個聚合根,要不然就可以定義成聚合根了
-
實體有自己的生命週期,他的生命週期從屬於聚合根。也就是聚合根沒有,實體也就沒了
比如我可以對訂單詳情的數據進行編輯,刪除。
-
聚合根與實體的關係通常是 1:N
因爲如果是 1:1, 通常不需要定義實體了。直接放在聚合根裏面,不需要唯一 id 了。
注意,聚合根裏面沒有實體,並不意味着數據庫就只有一張表,可以設計成多張表。DB 設計和領域建模沒有關係
- 可以單獨更新聚合根中實體數據
不是說只能有一個方法saveAggr(),可以有saveEntity()方法
案例
case 1:
品牌信息和店鋪
店鋪依賴品牌,但是店鋪有自己獨立的生命週期。他們的數據沒有一致性要求。所以店鋪是一個聚合根
case 2: 門店與門店商品
門店商品有自己的價格,返傭。需要單獨編輯,是一個實體。脫離了門店後沒有生命終結。
目前我們只討論了實體類型的聚合根,沒有討論業務過程的聚合根,比如轉賬
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s?__biz=MzI4NjI3MDc1NA==&mid=2247483822&idx=1&sn=85bd5d90da63654e55508b08226afb8b&chksm=ebde35e3dca9bcf500c2f4ee17d01712e7244fabfb9950ff5b8114fc9f9ec314847dbfc11e1b&scene=21#wechat_redirect