DDD聚合:一致性邊界 -James Hickey
在原始的域驅動設計書中,埃裡克·埃文斯(Eric Evans)對聚合解決了哪些問題進行了評論:
需要保持適用於緊密相關的物件組的不變性,而不僅僅是離散的物件。
什麼是不變式?
不變是業務規則,必須始終保持一致。
換句話說,我們的應用程式中經常會有跨越多個物件的業務規則。我們該如何處理?
聚合嘗試解決兩個主要問題:與業務規則和高爭奪性有關的一致性(即資料庫表中所謂的“鎖”)。
示例:圖書館預訂
如果圖書館有一個可供人們租用的龐大書籍/書卷怎麼辦?某個時刻只能一個讀者租界這本大書,如果將這本書的章節拆分成多本書,減少爭奪,則更多人可以分享這本書的內容。
假設所有這些作為物件存在於您的軟體中,一個龐大的物件模型將是一致的,但是會遇到爭用問題,很多人想租借同一本書籍怎麼辦?小物件將面臨更少的爭用,但是當多個使用者試圖修改這些小物件時,小物件之間將難以保持一致性。
事務一致性
考慮一下資料庫事務。當我們將事務提交到資料庫時,我們之所以這樣做,是因為所有相關資料只是真正地連在一起。
不變性內的一致性
讓我們採用一致性和不變性這兩個概念,並將它們融合在一起。
假設您正在使用時間跟蹤軟體。
兩位不同的經理正在增加為員工工作的時間。
這會很好,因為一位經理修改的日期與另一位經理修改的日期不同。實施的程式碼將每天分別獲取,並且它們也儲存為不同的資料庫行。因此,這裡沒有爭用問題。
當要求我們限制整個時間表的總工作量時會發生什麼?
在此示例中,當前整個時間表狀態目前是32小時,最大值不應超過40小時(這是我們的新業務規則)。兩個經理各自在兩個不同的日期(一個在週一,另一個在週二)增加了8個小時,兩者都將從資料庫中查詢時間有32小時,這時第一個加入的8小時已經成功完成了,而另一個操作已經獲取了時間狀態還是32個工作小時(banq注:類似資料庫ACID的髒讀),那麼第二個操作也會成功。這樣就有了48小時的時間表(但是業務規則是最大值不應超過40小時)。這種情況表明,我們還沒有建立某種一致性邊界。
增加一致性邊界
如果我們在整個時間表和相關物件周圍新增邊界,該怎麼辦?
我們可以將整個時間表視為所有可能發生的操作或其“內部”事物的“門戶”。
現在,整個時間表上的任何操作都必須透過聚合體。這個聚合體好像一個保鏢或代理者。
現在,我們已經在整個時間表上新增了一個一致性邊界,我們可以控制對其執行哪些操作。我們的邏輯並未分散在系統的不同部分。
注意:是的,爭用和鎖定仍然存在問題。我們將在另一篇文章中介紹。
經驗總結
將真實不變式建模為一致性邊界。不變性應驅動我們的總體設計。
不變性根據業務規則,但是,一項業務可能沒有複雜的規則,另一個可能有非常嚴格的規則。這將影響我們設計軟體的方式,從而影響總體邊界。
真正不變性
例如,假設我們正在建立一個影片遊戲,兩個人互相打架。
如果對手的健康點降低到0,會發生什麼。但是,他們沒有死?然而。
也許在幾秒鐘內,系統就會檢查,然後對手就會死去。那有意義嗎?沒有。
真正的不變式是那些需要在與該規則相關的操作相同的交易中保持一致的變數。換句話說,業務規則執行以後沒有必要被再次“檢查”。“檢查”或驗證應該是在某些操作進行時。(banq注:高實時的事務性)
例如,如果線上保險申請中的一項規則是確保申請人的信用評分足夠好以允許他們購買保險,該怎麼辦?
我們是否需要在申請人提交申請的同時進行檢查?不。
我們可以稍後再做,該系統將很有意義。
我們可以說保險申請最終是一致的。在將來的某個時候,當我們“等待”系統執行操作時,我們知道事情最終會解決。
作為業務流程,有意義的是,提交的申請“正在”被批准(或拒絕)。
從事務的意義上講,這些將不被視為真正的不變式。雖然,它們仍然是重要的業務規則。
結論
第一條經驗法則:將真實不變式建模為一致性邊界。花一些時間思考一下您的系統。什麼是真正的不變數的呢?哪一個不是?如果根據相關不變數對物件建模,會發生什麼?
原文點選標題
banq注:需要資料兩個表以上使用外來鍵等約束規則保持書籍一次性一致更改的,都可能需要放入一個聚合;或者,區分業務規則與業務流程,涉及到業務流程的長時間事務不能放入聚合,聚合跨時間邊界太大,但是業務規則與業務流程有時很難區分,業務規則透過業務流程來實現的。參考:https://www.jdon.com/54022
相關文章
- DDD聚合:樂觀併發 -James Hickey
- DDD本質是分而治之的分析方法 - James Hickey
- 領域驅動設計中的聚合是什麼? - James Hickey
- Clean架構中不好的部分 -James Hickey架構
- 建立微服務很容易,但是有幾點很難 - James Hickey微服務
- DDD之4聚合和聚合根
- DDD聚合設計原則
- DDD中聚合、聚合根的含義以及作用
- DDD聚合五種設計方法
- 《超越邊界》
- 二分查詢左邊界,右邊界,>=,>,<=,<
- 使用Spring Data JDBC實現DDD聚合SpringJDBC
- DDD聚合的數學模型 -Thomas Ploch模型
- DDD | 04-什麼是聚合根
- 人壽保險銷售平臺的領域驅動設計和事件風暴案例分享 -James Hickey事件
- 【AutoCAD .NET】如何在無邊界Hatch上選擇邊界點?
- 穿越邊界的姿勢
- 【二分】【邊界判定】
- AUTOCAD——快速提取邊界線
- React 錯誤邊界元件React元件
- 絕對值邊界法
- 使用Spring Data JPA實現DDD聚合的動態投影Spring
- DDD聚合的再一次定義 - Mathias Verraes
- 邊界佈局管理器
- Spring Data 2021.0增加了對DDD聚合更多自動支援!Spring
- 如何築造資料安全邊界
- 關於運營邊界的思考
- Pytorch 四種邊界填充方式(Padding)PyTorchpadding
- 打破邊界,邊緣計算有何應用場景?
- DDD聚合:整體行為不是由其部件組合而成的
- 視覺化學習:利用向量判斷多邊形邊界視覺化
- 寫網路爬蟲的法律邊界爬蟲
- 無邊界網路的劃分建立
- 黑盒測試方法之邊界值分析
- 實體類,邊界類和控制類
- 地理圍欄,打造智慧生活新邊界
- Go 效能提升tips--邊界檢查Go
- Python修改柱狀圖邊緣柱子與圖邊界的距離Python