2017-02-05 75 views
1

我想知道如何使用DDD和CQRS對日曆進行建模。我的問題在於越來越多的事件。我認爲日曆是包含事件(日曆事件)的聚合根。我不想在我的命令中使用ReadSide,但我需要在域級別檢查事件衝突的方法。聚集根包括大量的兒童

回答

4

我想知道如何使用DDD和CQRS對日曆進行建模。我的問題在於越來越多的事件。

「長壽命」聚合最常見的答案是打破這一生的情節。例如,會計師將在end of the fiscal year關閉的臨時帳戶。

在您的具體情況下,可能不是「日曆」,比如「二月日曆」,「三月日曆」等等,無論您的域名是否適合。

林不知道我是否正確DDD aproach在驗證方面。我相信重點不是讓模型進入無效狀態

是的,但無效狀態是一個棘手的事情來定義。 Udi Dahan提供this observation

一個微秒的時間差應該不會影響核心業務行爲。

更簡潔,處理命令A,接着通過處理指令B產生一個有效的狀態,那麼它也應該是真實的,你先結束了處理命令B,然後A.

讓我們選擇你的「事件碰撞「的例子。假設我們處理scheduleMeeting(A)scheduleMeeting(B)兩個命令,並且域模型理解AB碰撞。謎語:我們如何確保日曆保持有效狀態?

不失一般性,我們可以翻轉硬幣來決定哪個命令先到達。我的硬幣出現尾巴,因此命令B首先到達。

on scheduleMeeting(B): 
    publish MeetingScheduled(B) 

現在會議指令A到達。如果您的有效日曆不允許衝突,那麼你的實現需要看起來像

on scheduleMeeting(A): 
    throw DomainException(A conflicts with B) 

在另一方面,如果你擁抱的想法,命令到達應該不會影響結果,那麼你需要考慮另一種方法。也許

on scheduleMeeting(A) 
    publish MeetingScheduled(A) 
    publish ConflictDetected(A,B) 

也就是說,Calendar聚合被建模爲不僅跟蹤計劃的事件,而且跟蹤已經出現的衝突。

另請參閱:aggregates and RFC 2119

+0

謝謝你的回答。關於將日曆分成幾個月的想法對我來說似乎完全有效。林不知道我是否正確DDD aproach在驗證方面。我相信關鍵是不要讓模型進入無效狀態 - 這意味着必須通過日曆瞭解所有自己的事件(如Agreggate Root)。 – ayeo

+0

我想你需要詳細解釋一下系統如何利用最終一致性,因爲你描述它的方式,你仍然需要較大的聚合邊界以檢測甚至發生了衝突。通過最終的一致性,事件可以是單獨的聚合,您可以完全擺脫日曆中事件的集合(將其替換爲查詢)。 – plalx

+0

當我在做某種資源管理時,我最終得到了Day的概念。不出所料,其他從業者也得出了同樣的結論。您可以同時具有活動和日期,並檢查它們是否相互兼容(日期有空,活動可以降落到幾天)。 –

3

事件也可能是一個聚合根。我不知道你的商業約束,但我認爲,如果兩個事件colide你可以通知用戶以某種方式採取手動操作。否則,如果你真的真的需要他們不要colide你可以使用快照來加速巨大的日曆AR。

我不想在我的命令中使用ReadSide,但我需要在域級別檢查事件衝突的方法。

您無法在集合命令處理程序中查詢讀取模型。對於碰撞檢測,我會創建一個特殊的DetectColisionSaga,訂閱EventScheduled事件,如果發生碰撞,應該檢查(可能是異步,如果是多個事件)並以某種方式通知用戶。

+0

謝謝,但訪問被認爲是良好做法的域的讀方? – ayeo

+0

你是什麼意思的「域」?你的意思是寫作方面? –

+0

是的,基本上就這個問題而言,我的意思是寫一面。就我掌握的命令而言,它們應該直接在域模型上執行(由處理程序執行)。 – ayeo