2011-01-08 18 views
6

實現域事件時,應該僅將事件處理程序用於純粹的域關注;你會與業務專家討論的東西,還是他們開放供任何對域模型感興趣的東西使用?域事件處理程序 - 它們是否應用於應用程序層問題?

這很可能是最好的解釋一個簡單的例子,考慮日曆應用程序爲員工安排工作。

我們可能有以下域事件中......

AppointmentAdded AppointmentRemoved AppointmentContentChanged AppointmentMoved

我們對這些事件處理程序,例如,當一個約會移動到時候員工之外工作時間我們設置了警告標誌。

當然有對這些事件感興趣的應用顧慮,例如,當約會被添加到日曆中時,我們應該將其添加到工作單元中,以便稍後可以進行更改。

這些應用程序是否應該擔心域事件的消費者,還是應該引發和處理單獨的系統事件?

回答

5

在DDD解決方案中有兩種使用事件的方法。

第一個是基於Udi Dahan的articles about events。如果你還沒有閱讀過,我強烈建議。總之,它表示您使用靜態類以及正常的ORM樣式行爲發佈您的事件。因此,您將訂單添加到您發佈活動的客戶訂單收集。由於您的域行爲是在事務處理範圍內執行的,因此事件處理程序也是如此。您也可以在那裏找到並建議不要手動將對象附加到工作單元。應該通過調用現有的行爲來創建新的聚合根。

Greg Young提供了另一種選擇。它基於事件採購,基本上是使用事件作爲持久狀態的手段。在這種方法中,聚合根通常使用一些基礎設施(例如基本聚合根類)來應用事件。應用程序確實會調用聚合根類上的事件處理程序在總線上發佈此事件(無論您使用哪種總線實現)。

2

如果你的意思是橫切關注點,那麼如果你的應用程序邏輯需要它,你將不得不使用它。所以它將與其他事件處理代碼混合使用。

但是,如果您在發生域事件時需要做幾件獨立的事情,那麼最好使用單獨的事件處理程序(請參閱Separation Of Concerns原則)。

在第一種情況下,請儘量避免將域邏輯與事件處理(基礎架構)邏輯混合。事件處理程序調用域方法時,左側基礎結構/交叉關注代碼。在域對象的方法內移動域代碼。

+0

這聽起來很合理,但它引發了一個關於何時提升域事件的新問題。比方說,在一個事務中執行向日歷添加預約,將實體添加到UnitOfWork必須在事務中執行,但更新UI必須在事務之外執行。在這種情況下,域名事件是否應該在交易中提出?並且UI更新應該在另一個域事件處理程序中完成,它是否工作異步。 – Andronicus 2011-01-14 13:25:13

+1

域事件代表已發生的事情。所以應該沒有能力在事件處理程序中回滾事務。提交事務,然後調用事務處理程序來處理事務中發送的所有事件 – 2011-01-14 15:07:26