2016-06-09 11 views
0

讓我說我有一個持久化事件流,根據我定義的一些「模式」建立一個有效的狀態。活動升級後和修補之前在事件採購中有無效狀態是否可以接受?

我改變了模式,事件升級以反映這一點。

但是,有些狀態只能通過升級事件才能生效,我還需要添加更多事件來修補狀態以使其完全有效。

首先,就事件採購而言,這種推理是否有效?

如果是這樣,我該如何處理特定版本的狀態不再有效的情況?我的意思是這可以接受嗎?是否仍有可能對無效狀態的版本進行補水?如果這是一種寫模式,它不是最新版本,我無法修改這個狀態,所以也許沒什麼大不了的?

回答

0

但是,有些狀態只是通過升級事件才能生效,我還需要添加更多事件來修補狀態以使其完全有效。

「補償事件」是通常的術語;記錄簿中存在筆誤,因此我們需要在歷史記錄中添加一個新事件來糾正錯誤。

如果是這樣,我該如何處理特定版本的狀態不再有效的情況?

通常,您要謹慎,非常謹慎地引入任何自動驗證,以防止您加載無效的歷史記錄。記住,狀態只是狀態;業務規則限制了域允許改變的方式。離開破碎的狀態可讀,但破碎,是安全的。

特別是,如果允許加載狀態,那麼枚舉事件流,測試對象的最終狀態以及爲產生無效狀態的任何流生成一個異常報告是一個簡單的練習,他們對運營商/管理層進行處理,等等。

假設您對輸入驗證合理謹慎,並比較您提出的命令是否與最新已知狀態一致(聚合實施業務規則,但他們不需要爲自己囤積這些規則),那麼您可能可能實現足夠低的錯誤率,以至於不需要進行有效的數據驗證。當錯誤易於檢測並且便宜修復時尤其如此。

否則,凍結任何聚集體處於無效狀態是防止進一步損壞的好方法。

但是,如果你確實需要這個狀態保持有效,那麼你可以使用補償事件來玩。

考慮:事件採購的基本模式看起來像

History history = repository.getHistoryById(id) 

State current = State.SEED 

for (Event e : history) { 
    current = current.apply(e) 
} 

實際上,有一個隱藏的概念,在這裏,它封裝邏輯來將它們傳遞給狀態之前處理事件。隱藏,因爲null情況只是將枚舉的事件直接傳遞給目標。

History history = repository.getHistoryById(id) 
Historian historian = new Historian(); 

State current = State.SEED 

for (Event e : historian.reviewEvents(history)) { 
    current = current.apply(e) 
} 

歷史學家讓你把你的補償事件邏輯的地方 - 根據自身的狀態,歷史學家經過大多數事件,但修復知道需要編輯/補償/刪節

凡的人歷史學家的狀態是從哪裏來的?當然,從歷史學家的歷史來看,爲什麼呢?您將事件更正的歷史記錄加載到歷史記錄中,然後讓歷史記錄清理彙總事件。

如果你需要修正歷史學家?它一直都是烏龜!每個流都有一個獨特的歷史學家;歷史數據流的標識符是從它過濾的數據流中計算出來的(例如,名爲UUID的數據庫允許您執行此操作)。因此,對於每個流,您檢查是否存在歷史流;當你發現一個不存在的東西時,你就知道停止搜索並使用空歷史記錄,捲起更改,處理最後的事件序列以重新生成你的真實對象的狀態,然後離開你。

請注意,我在任何地方都沒有看到這個想法的參考實現;這是白板的聲音,但事實是,我一直在我自己的設計中推遲這個要求。

相關問題