2013-01-15 60 views
4

我正在實施使用事件採購的有界上下文,但遇到了問題。假設我正在模擬一場足球比賽,並且我對個人進球(得分等)和總成績感興趣。所以如果我有一個Match聚合根,我最好想要提出的事件叫做GoalScored和ScoreChanged。我希望從這個領域明確表達的分數的原因是,我不希望很多不同的聽衆和其他有界的上下文都計算相同的東西。事件採購鏈接事件

這看起來很簡單,但:匹配對象有一個Goal()方法,它添加了一個新的目標。本着事件採購的精神,這不會直接改變匹配狀態,但會引發一個在匹配中處理的GoalScored事件,然後突變狀態(以及將事件推送到非標準化器)。因此,就提高ScoreChanged而言,直到GoalScored事件得到處理之前,得分並沒有真正改變,那麼我是否會針對該事件引發另一個事件(ScoreChanged),從而有效地鏈接事件?我不這麼認爲,當一個聚合根從事件存儲庫重新加載時開始,每次都要創建大量額外的事件來響應每個GoalScored。

我也考慮過在提高GoalScored的命令處理程序中計算得分會是多少,會出現'假設'的情況。然後我可以在命令處理程序中引發這兩個事件。我真的寧願不這樣做 - 它看起來並不合適。製作足球比分足夠簡單,但其他比賽(例如板球)需要更多的工作。

我可以把目標和得分都放在GoalScored事件中,這足夠公平,但它看起來並不正確 - 得分與GoalScored事件本身無關。

討論事件採購時使用的所有示例似乎都使用電子商務客戶/訂單域,而我從未見過類似的情況。

有沒有人有處理這種情況的經驗?

感謝

回答

11

乾淨域事件的選擇,就像其他的造型,應該導致了在該領域鏡像概念。你說「得分與GoalScored事件本身無關」。但它確實如此。在足球方面,得分可以改變的唯一方式是如果進球。儘管可以收回目標,例如越位通話或其他處罰。目前還不清楚你是否要模擬這個模型。

域方法一次發出多個事件是很常見的。一個好的框架可以很容易地將它們看作一堆,例如作爲一次提交。爲什麼不放出GoalScored和ScoreChanged事件?

您可能還想考慮這個域是否有任何命令。足球比賽本身就是記錄系統。來自比賽的事件已經成爲歷史記錄。你可能只是寫一個處理事件流成更多事件流的系統?

+0

是的我可能會只從一個方法發出這兩個事件。 該域確實有命令 - 至少如果我們正在說相同類型的命令。 StartMatch,PlayerSentOff等等。 最後一點,它看起來很像一個將事件流處理成更多事件的系統,當然也用於評分方面。 感謝您的回答。 – user303754

3

有一件事情在考慮事件採購時常常會幫助你注意你的時態 - 你說的是StartMatch,但事實上它實際上是事件MatchStarted。

至於ScoreChanged,你是否在比賽之外使用此事件?如果不是,Score應該是可公開訪問的唯一部分,而GoalScored事件只是改變了這一點。這使得CQRS以小的方式存在(我如何得分並不取決於我如何改變它)。然後分數可以在內部保持一個狀態,或者可以重放所有的GoalScored事件以在每次被調用時到達一個數字。設計合理的事件源解決方案的'感覺'可以始終從事件中重新生成任何狀態。

現在,如果ScoreChanged需要警惕系統的其他部分(例如玩家排名),則可以將事件多播到不同的根,或者您可能需要重構設計。在這種情況下,你是想實時更新玩家,還是僅在比賽結束後才更新?