ドメインイベント

ドメインに影響を与える興味深い事象のメモリをキャプチャします。

2005年12月12日

これは、2000年代半ばに執筆していた「Further Enterprise Application Architecture development(エンタープライズアプリケーションアーキテクチャ開発のさらなる展開)」の一部です。残念ながら、それ以来、他の多くのことが私の注意を引いており、それらをさらに進める時間がありませんでしたし、近い将来にも時間が見込めません。そのため、この資料はまさにドラフト形式であり、再び作業に取り組む時間を見つけるまでは、修正や更新は行いません。

火曜日にBabur'sで食事をし、クレジットカードで支払いました。これは、イベントタイプが「購入」、対象が私のクレジットカード、発生日が火曜日であるイベントとしてモデル化できます。Babur'sが古い手動システムを使用していて、金曜までトランザクションを送信しない場合、通知日は金曜日になります。

物事は起こります。すべてが興味深いわけではなく、記録する価値はあるものの、反応を引き起こさないものもあります。最も興味深いものは反応を引き起こします。多くのシステムは、興味深いイベントに反応する必要があります。システムがなぜそのように反応したのかを知る必要があることがよくあります。

システムへの入力をドメインイベントのストリームに集約することで、システムへのすべての入力の記録を保持できます。これは、処理ロジックの整理に役立ち、システムへの入力の監査ログを保持することもできます。

仕組み

ドメインイベントの本質は、開発中のアプリケーションの状態の変化を引き起こす可能性のあるものをキャプチャするために使用することです。次に、これらのイベントオブジェクトが処理されてシステムに変更が加えられ、監査ログを提供するために保存されます。

図1:イベントは入力を単一のソースに集約します。

図1は、この点を説明するのに役立ちます。ここでは、ユーザーインターフェース、メッセージングシステム、およびデータベーステーブルの直接操作からの入力を備えたシステムがあります。これらをドメインイベントに解決するために、これらの各入力ストリームと対話し、入力を永続ログに格納されるドメインイベントのストリームに変換するコンポーネントがあります。次に、イベントプロセッサはログからイベントを読み取り、それらを処理して、アプリケーションが想定どおりに動作するようにトリガーします。

このストリームでは、システムの最初の入力層は、イベントを作成してログに記録する以外に、刺激に対して何もアクションを実行しません。次に、2番目の層は実際の入力ソースを認識できず、イベントに反応して処理するだけです。

この例では、1つのイベントログのみを示しています。実際には、イベントの応答要件が異なる場合、ログを分離するのが理にかなっていることがよくあります。ユーザーインターフェースは通常、多くのリモートメッセージングシステムよりもはるかに高速な応答時間を必要とするため、ユーザーインターフェーストラフィックを別のログに配置し、それらに個別のプロセッサを使用するのが理にかなっています。

この図は、非同期パイプとフィルタースタイルの相互作用を暗示していますが、これはこのアプローチの本質的な部分ではありません。実際、特にユーザーインターフェースの刺激では、UIハンドラーが同期相互作用でイベントプロセッサを直接呼び出すのが一般的なアプローチです。

ドメインイベントは、外部刺激からの情報をキャプチャします。これはログに記録され、ログを監査証跡として使用するため、この**ソースデータ**が不変であることが重要です。つまり、イベントオブジェクトを作成したら、このソースデータは変更できません。ただし、イベントには、システムがイベントに対して何をしたかを記録する別の種類のデータもあります。これを**処理データ**と呼びます。ドメインイベントのデータを、イベントの内容をキャプチャする不変のソースデータと、システムがイベントに応答して何をするかを記録する可変の処理データとして特徴付けます。クレジットカードの請求のソースデータには、請求額、ベンダーなどがあります。処理データには、表示された明細書が含まれる場合があります。プラットフォームが不変オブジェクトを特にサポートしている場合は、これを利用するためにイベントを2つのオブジェクトに分割する価値があるかもしれません。

ソースデータは変更できませんが、システムが変更を処理する必要がある場合があります。これは通常、元のイベントが正しくなかったためです。この変更を個別の遡及イベントとして受信することで、これを処理できます。次に、プロセッサは遡及イベントを処理して、以前の誤ったイベントの結果を修正します。多くの場合、この処理は非常に一般的なレベルで実行できます。

3番目の、しかし時折発生するイベントデータのカテゴリは、イベントストリーム上の他のデータからの派生からキャッシュされたデータです。これらの場合、イベントプロセッサは現在のイベントを処理しながら過去のイベントからの情報を要約し、その要約されたデータを現在のイベントに追加して、将来の処理を高速化します。他のキャッシュと同様に、このデータは自由に削除して再計算できるという事実を通知することが重要です。調整が発生した場合。

異なるイベントは異なる理由で発生するため、異なるタイプのイベントを使用するのが一般的です。次に、イベントプロセッサはイベントタイプをディスパッチメカニズムの一部として使用します。イベントのタイプは、イベントのサブタイプ、個別のイベントタイプオブジェクト、またはその両方の混合を使用して表すことができます。

異なるタイプのイベントが異なるデータを運ぶことは非常に一般的であるため、イベントタイプにイベントのサブタイプを使用すると、うまく適合します。サブタイプの問題は、これによりタイプの急増につながることです。これは、データの多くが同じである場合に特にイライラします。ハイブリッドアプローチでは、サブタイプを使用して異なるデータを処理し、イベントタイプオブジェクトを使用してディスパッチを通知します。

イベントはある時点で何かが起こることなので、イベントに時間情報が含まれるのは当然です。これを行うときは、イベントに格納できる2つの時点を考慮することが重要です。イベントが世界で発生した時刻と、イベントが認識された時刻です。これらの時点は、実際の時刻と記録時刻の概念に対応しています。

もちろん、両方の時点が常に必要なわけではありませんが、両方が必要かどうかを常に検討する必要があります。危険なのは、1つの時点を選択し、どの時点を選択したかを、その時でも後ででも明確にしないことです。そのため、どちらであるかを示すために時点に明確な名前を付けることをお勧めします。

イベントがさまざまなシステムによっていつ認識されたかを記録するために、複数のレコード時点が必要になる場合があります。

いつ使うか

ドメインイベントを介してシステムの刺激をキャプチャすることは重要な決定です。これは、アプリケーションに明確なアーキテクチャスタイルと、少なくとも最初はぎこちなく見えるプログラミングモデルを課します。現時点では、このアプローチに慣れたら、実際にはもっと努力が必要かどうかは明らかではありません。

その ungewöhnliche な性質にもかかわらず、このアプローチを使用することには大きな利点があると考えています。

イベントの監査ログは、監査とデバッグの両方の目的に役立つ完全な記録を提供します。システムが奇妙な状態になった場合、そこに到達した入力の完全なログがあります。実際に処理されたイベントを保存することにより、監査ログに重要な情報を書き込むことを怠る可能性が低くなります。

明確なイベントストリームにより、メッセージルーターを追加してイベントを新しいシステムに転送することにより、他のシステムが将来アプリケーションの一部または全部を置き換えることが容易になります。システムの最終的な消滅を促進する方法でシステムを設計することは流行していませんが、システム交換プロジェクトの頻度が高いため、もっと注意を払う必要があります。

ドメインイベントは、イベントソーシングに必要なパターンとして特に重要です。イベントソーシングは、*すべて*の更新がドメインイベントを介して行われるようにシステムを編成します。