簡體   English   中英

事件采購:在哪里放置業務邏輯

[英]Event Sourcing: where to put business logic

我可以想到兩個地方將域邏輯放在事件源系統中,或者有一個缺點。

  • 在Aggregate的事件處理程序中,在創建事件后在本地調用。 (這是我在大多數例子中看到的,盡管他們中的大多數都有非常簡單的邏輯)
    問題 :存儲在事件存儲中並發布給訂閱者的事件不包括此處理的數據,因此在投影上必須將相同的邏輯應用於事件。
  • 在創建活動之前。 現在處理后的數據可以存儲在事件中,並且投影不必知道任何有關業務邏輯的信息。 (我在示例中沒有看到這種方法)
    問題 :在這種情況下,雖然事件僅包括可能導致信息丟失的已處理數據。
    更糟糕的是:由於已經計算了事件數據,我還放棄了通過重放事件來糾正錯誤的業務邏輯的可能性。

示例 :根據某些數據計算指標。
要么我必須計算兩次指標(在域模型中一次,在投影中一次)
或者我必須在發送活動之前計算它並將其包含在那里。

控制流程通常如下:

  • 命令被發送到命令處理程序,並且命令中的屬性被預先驗證,就像身份指向現有實體並且所有必需信息都存在且格式正確
  • 命令處理程序從存儲庫中檢索聚合(通過讀取事件流,但這並不重要)並根據此命令需要執行的操作調用聚合方法
  • 聚合方法必須確保其參數和聚合狀態相互允許執行操作。

  • 然后,Aggregate方法創建一個事件並調用此WhenApply方法來處理事件

  • 事件處理程序改變聚合狀態,沒有邏輯!

  • 然后將控制流返回到命令處理程序,它將持久存儲在商店中的所有新事件

進一步行動與預測有關。

在應用事件之前將不變保護(即業務邏輯)放入聚合事件的原因是因為生成事件時沒有回頭路。 這件事已經發生了。 你不能拒絕申請活動。 考慮從事件流中恢復聚合時重放事件(從存儲庫讀取),如果有一天你決定在那里使用if-throw組合,那么這可能會如何工作?

簡而言之:

  • 在發送命令之前應用初始邏輯
  • 命令處理程序中還有一些額外的邏輯
  • 聚合方法中的聚合保護(很可能也在命令處理程序中)
  • 事件處理程序中沒有邏輯,只有狀態變異

沒有人說事件采購會幫助你解決計算中的問題。 要創建一個額外的安全網,您可能希望保存命令,但是您必須發出補償事件或截斷流,這實際上並不是您想要做的。

我想你的Aggregate Root中有一些狀態。 這應包含有關您業務的邏輯。 因此它應該有足夠的數據來基於命令創建事件。
此事件的消費者(查詢模型)進行計算。 因此,如果意圖是計算平均值,則必須設法以給定方式存儲自身。
我做了類似的事情。 一旦它成為業務邏輯的一部分,它就在Aggregate中,一旦它在Query模型中,因為它不是業務邏輯的一部分,而是更多的度量計算。
不要害怕將數據存儲在多個地方。 一致性的責任應該委托給事件分發,而不是您的業務邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM