DDD聚合的數學模型 -Thomas Ploch
軟體不是孤立的工件。它必須嵌入到使用和生產它的人們的社會技術環境中,並與環境不斷相互作用。我們需要知道的是,複雜的系統如何顯示我們作為系統設計者試圖捕獲有用的抽象的行為。
“組織是動態的,層次結構化的實體。這種活力體現在每個組織級別的重大事件的出現。”
[ Morgeson F.,Mitchell T.和Liu D.2015。事件系統理論:面向事件的原始科學方法 ]
我們將這些事件稱為事件處理events processes模式。系統通過事件處理才能實現目標,例如線上銷售書籍或向餐廳提供座位預訂。一個稱為處理理論(process theories)的大型研究主題正在試圖瞭解事件的模式如何導致積極的結果。歸根結底,它們是“關於發生了什麼事以及誰在什麼時候做了什麼的事情(事件),事件、活動和選擇隨時間變化”(Langley,A。1999。根據過程資料進行理論化的策略)。
協作時間建模的興起
在過去的幾年中,出現了捕獲這些事件處理的新方法。事件風暴,故事對映或領域故事講述都是這些方法的示例,這些方法可以認識到了解事件的重複模式,能在設計可行的解決方案中發揮很大的作用。與傳統的靜態建模技術相比,這些方法通常與組織現實的重疊更大。
時間建模還影響了經驗豐富的DDD從業人員在使用聚合Aggregates時所做的戰術設計選擇。將聚合定義為命令(來自環境的刺激),行為(對可以改變系統響應機制的傳入刺激的反應)和事件(響應系統狀態變化的系統訊號)的組合。例如,“事件溯源”模式就是建立在這些基本設計選擇的基礎上,使事件的按時間順序排列(即“時間”)模式成為其設計的核心要素。
如果我們可以通過按時間順序排列的一系列事件定義一些聚合,那麼這些聚合也是處理process。
重新發現有限狀態機
建模過程在計算中並不是什麼新鮮事物。而自動機理論似乎特別有趣:
有限狀態機(FSM)公式用於描述根據一組規則資訊或任務從一種狀態移動到另一種狀態以採取行動的過程。狀態包含最少的資訊,這些資訊與輸入的知識一起可以確定輸出。
術語“ 自動機”和“ 機器”可互換使用,因此,當我們談論FSA時,也指FSM。
轉換為我們的處理process術語後,FSM會處理系統激勵流(命令),強制執行不變式並更改系統狀態(行為)。
一個FSM Α是一個5元組:
A =⟨S,C,δ:S x C→S,S₀,F:F⊂S⟩
- S是一個非空的有限狀態集
- C是命令語言,一種非空的有限命令集
- δ是行為的集合—狀態和命令與狀態的關係
- S₀是初始狀態
- F是最終狀態的非空有限集,其中F是S的子集
有了這個定義,我們將需要從領域專家的知識中得出命令和狀態字母,然後通過行為功能將點連線起來。
宇宙是一個混亂的地方
我們樂於尋找確定性的解決方案,以解決複雜的問題,而這種方式本質上不是確定性的。作為一種建模方法,DDD包含了系統的意外行為-這是我認為將DDD思維應用於複雜問題幾乎總是一個好選擇的主要原因之一。這意味著根據當前情況,對系統刺激的反應通常會有所不同。想象自己是一個呼叫中心代理,突然被建議將針對特定主題的呼叫重新路由給主管。世界只是不可預測的。
非確定性有限原子自動機(NDFA)
為了解決這個混亂的世界,自動機理論提供了兩種可以表達這些差異的FSA型別-非確定性(NDFA)和確定性(DFA)FSA。
DFA和NDFA之間的差異很小。DFA對於每個狀態和命令對僅具有一個轉換,而NDFA可以具有多個轉換,甚至沒有。從數學上講,它們都是等效的。您始終可以將DFA轉換為NDFA,然後再次返回。
但是,在表示它們所需的複雜程度之間確實存在差異。具有n個狀態的NDFA 可以轉換為具有2個狀態的DFA 。對於10個狀態的相當複雜的NDFA,我們在DFA中最多需要1024個狀態來表示它!
使用NDFA時,您為了簡化而犧牲了確定性!
事件在哪裡?
如果我們重新收集FSA的定義(由命令和狀態語言與“行為”配對定義),則可能會認識到當前尚無辦法將任何訊號發回系統。那麼,事件在哪裡?
普通的NDFA似乎不足以代表我們的處理process。自動機理論是否可以提供在這種情況下可以使用的另一個概念?
劇透:是的,可以!
引入有限狀態傳輸器(FST)
讓我們看一下有限狀態感測器的正式定義。這是一個六元組:
⟨=⟨S,C,E,δ:S x C→S,S₀:S₀S,ω:S x C→E→
- S是一個非空的有限狀態集
- C是命令語言,一種非空的有限命令集
- E是事件語言,非空的有限事件集
- δ是行為的集合,即狀態和命令對與形式為δ的狀態的關係:S x C→S
- S₀是初始狀態的非空有限集,其中S₀⊂S(S₀是S的子集)
- ω是狀態和命令對與形式為ω的事件的輸出關係:S x C→E
現在我們有了命令,行為和事件,我們可以將process建模為非確定性FST。讓我們開始行動並在示例場景中使用數學!
示例:設計使用者註冊過程
假設我們有一個很棒的Event Storming會議,現在正嘗試將數學應用於特定問題的緊縮知識-使用者註冊過程。我們必須定義命令,狀態和事件等名詞,而行為和事件是響應特定的行為而輸出的。
1. 我們從構建事件語言開始。
- 傳送確認郵件開始註冊後,我們要確保客戶確實可以訪問提供的電子郵件地址,因此我們通過帶有確認連結的電子郵件傳送確認郵件。
- 確認重發當確認已過期,我們想使我們的客戶能夠輕鬆地重新傳送確認,也許以前的郵件被垃圾郵件過濾器捕獲。
- 帳戶已確認當客戶完成確認後,我們說該帳戶現已確認。
- 帳戶是通過GDPR請求刪除的。根據歐洲法律,我們有義務刪除所有個人資料。
它遵循:
Ε = {ConfirmationSent,ConfirmationResent,AccountConfirmed,AccountDeleted}
2.類似於事件的命令:
- 開始註冊
- 確認帳號
- 重發確認
- 滿足GDPR要求
它遵循:
C = {StartRegistration,ConfirmAccount,ResendConfirmation,FulfillGDPRRequest}
3. 設計狀態
在設計狀態時,我們應該牢記一個原則:
狀態包含最少的資訊,這些資訊與輸入的知識一起可以確定輸出。
我們的目標是找到所需的最少資訊量,以進行適當的反應。在這裡,少就是多。
該示例不著重於管理資料,但是可以定義狀態的屬性-這不會影響通用公式。
- 潛在客戶這是我們的初始狀態。任何未註冊的客戶都是潛在的!
- 需要確認
- 已確認
- 已刪除
S = {PotentialCustomer,RequiresConfirmation,Confirmed,Deleted}
和
S₀ = { PotentialCustomer }
4. 反應
我們需要做的最後一件事是定義行為(δ)和事件(ω)函式。
δ : S x C → S = { (PotentialCustomer, StartRegistration) → RequiresConfirmation, (RequiresConfirmation, ResendConfirmation) → RequiresConfirmation, (RequiresConfirmation, ConfirmAccount) → Confirmed, (Confirmed, FulfillGDPRRequest) → Deleted, (RequiresConfirmation, FulfillGDPRRequest) → Deleted } |
和:
ω : S x C → E = { (PotentialCustomer, StartRegistration) → ConfirmationSent, (RequiresConfirmation, ResendConfirmation) → ConfirmationResent, (RequiresConfirmation, ConfirmAccount) → AccountConfirmed, (Confirmed, FulfillGDPRRequest) → AccountDeleted, (RequiresConfirmation, FulfillGDPRRequest) → ϵ } |
完工
現在,我們終於可以將我們的使用者註冊彙總(或更確切地說是不確定的有限狀態轉換器)構造為:
Τ=⟨S,C,E,δ,S₀,ω⟩
並向其傳送以下命令:
I = { StartRegistration, ResendConfirmation, ConfirmAccount, FulfillGDPRRequest } |
作為迴應,我們將收到以下事件:
E = { ConfirmationSent, ConfirmationResent, AccountConfirmed, AccountDeleted } |
結論
- 我們已經瞭解到,面向process的時間模型在處理複雜系統的行為時非常匹配-以及協作建模技術如何塑造了我們對這些系統的理解。
- 我們回顧了計算技術的過去,以重新發現自動機理論作為對流程進行建模的一種手段,探索了不同型別的機器(FSA,DFA,NDFA,FST),並將它們對映到時間聚合設計的所需屬性。
- 我們將數學付諸實踐,並設計了一個“使用者註冊彙總”作為具體示例。
點選標題見原文原圖。
相關文章
- DDD之4聚合和聚合根
- DDD中聚合、聚合根的含義以及作用
- DDD聚合設計原則
- DDD聚合五種設計方法
- 分散式機器學習中的模型聚合分散式機器學習模型
- 使用Spring Data JDBC實現DDD聚合SpringJDBC
- DDD聚合:樂觀併發 -James Hickey
- DDD | 04-什麼是聚合根
- 使用Spring Data JPA實現DDD聚合的動態投影Spring
- DDD聚合的再一次定義 - Mathias Verraes
- 運用領域模型——DDD模型
- DDD模型探索的Whirl pool設計流程模型
- DDD聚合:一致性邊界 -James Hickey
- DDD聚合:整體行為不是由其部件組合而成的
- 貧血模型 - DDD - The Domain Driven Design模型AI
- 在DDD中建立領域模型模型
- 數學模型——數學與人類文明的橋樑模型
- Stream流收集器的購物車DDD聚合真實示例 - foojay
- Spring Data 2021.0增加了對DDD聚合更多自動支援!Spring
- 關於聚合根,領域事件的那點事---深入淺出理解DDD事件
- 模型驅動設計的構造塊(上)——DDD模型
- 貧血模型與充血模型比較 - DDD - The Domain Driven Design模型AI
- DDD中簡單模型比複雜模型更危險模型
- DDD的實體、值物件、聚合根的基類和介面:設計與實現物件
- 機器學習引數模型與非引數模型/生成模型與判別模型機器學習模型
- 學習真DDD的最佳路徑
- Elasticsearch聚合學習之二:區間聚合Elasticsearch
- Spring Data JDBC如何對DDD聚合根進行部分更新? - spring.ioSpringJDBC
- 用“資料與演算法”解釋DDD“上下文和聚合”演算法
- 領域驅動設計(DDD)中模型的重要性 - Jeronimo模型
- 領域驅動模型DDD(一)——服務拆分策略模型
- 敏捷史話(五):敏捷已逝 —— Dave Thomas敏捷
- DDD的函數語言程式設計實現函數程式設計
- 通過語言的比喻句發現隱藏的DDD模型 - verraes模型
- 引數匹配模型——Python學習之引數(二)模型Python
- Python小白的數學建模課-09 微分方程模型Python模型
- 領域驅動模型DDD(三)——使用Saga管理事務模型
- MongoDB學習之聚合操作MongoDB