ドメインイベントとは?
対象とするシステムで何かの出来事が起きたときに扱う仕組み。システム間の連携を柔軟にします。
業務的な出来事をドメインイベントとして発生させ、それらを同期的、非同期的に処理することでシステムとしての整合性を維持するようにする。
ドメインエキスパートが話す「〜するときに」や「〜した場合」に注目すること。(エンティティや値オブジェクトはオブジェクトの属性や振る舞いに着目して設計が必要でしたが、ドメインイベントは「ドメインエキスパートが注目する出来事」に着目して設計します。)
具体的には
- 特定のシステムで発生したことを外部システムに通知する場合
- 境界づけられた同じコンテキスト内のトランザクションを分離したい場合
メリット
結果整合性を用いたシステムの構築が容易になる。
密結合になりがちな他システムとの連携や、他の集約へのデータ反映を疎結合にできる。
バッチ処理をなくせるかも
発生したイベントを随時通知するので、夜間バッチなどをなくせるかもしれない。(発生したイベントは随時取り込む形の設計にした場合は)
要素
パブリッシャー
イベントの発行を行う。
サブスクライバー
イベントの受信を行う。サブスクライバが処理する内容は以下三つ。
同期処理
イベントに応じた処理をイベント発行と同じトランザクションで実施。サブスクライバで処理は完結する。
イベント格納処理
同一トランザクションではイベントの記録だけ行う。
分散処理
イベントを他システムにリアルタイムで転送し、2フェーズコミットなど分散トランザクションで制御する。分散トランザクションは製品固有の知識が必要になるので非常に実装難易度が高いです。
流れ
- 集約のコマンドでドメインイベント生成
- ドメインイベントパブリッシャーがイベントを発行する。
- サブスクライバがイベントを受信(購読)する。
- サブスクライバでメールを送信する。
ドメインイベントのクラス設計
不変クラスとして設計します。コンストラクタでは値を設定することのみ可能でプロパティは読み取り専用となる。
また、イベントを使って外部コンテキスト連携だったりメッセージングをする場合は一意な識別子の実装が必要になる。(イベントは複数回受信することを想定して重複排除するため)
実装
クラス名
例えば、「gitにコミットした時」みたいな場合を想定するなら以下のような命名をします。
「GitCommited」(〜〜をコミットしたとき)などとつけます。
共通項目
- 発生タイミング(OccurredOn)
- 発生バージョン(EventVersion)
その他項目
- イベントの発生要因を示す情報
この記事へのコメントはありません。