基礎
さまざまな便利な機能を構築できる主要なメカニズムは次のとおりです。
- 各イベントには、その値を定義する名前、つまり セマンティクスがあります。 同意します。「 イベント1 」と「 シップセーリング 」には大きな違いがあります。
- エンティティのイベントの数に制限はありません。 したがって、新しいイベントは、コミットされたアクションの新しいタイプと同様に反映でき、既存のイベントを拡張できます。たとえば、2番目のバージョンに新しいプロパティが追加されました。
- 発生したイベントは不変です。
「クッキー」
当然、アプローチが適用されると、それは非常に同じ「IT」を持っていることを意味し、ゲームはろうそくの価値があります。
イベント履歴
そもそも、イベントソーシングは、システム内で発生した「どのように、なぜ」、「何を、いつ」をすべて記憶したい人にとっての夢です。 これがレコードの監査であり、「なぜ」情報を保存することによってのみ改善されるとしましょう。 グレッグヤングが彼のプレゼンテーションの1つで使用した例を覚えています。
銀行は、顧客の居住地に関する情報と、ある日、住所の1つが変更されたという情報を保存します。 テーブルに情報を保存すると、レコードが更新された最大値を確認できます。 監査が関連付けられている場合、一般に、以前のすべての値の履歴を確認できます。 しかし、なぜ変わったのかを知ることができます:これは元々の間違いだったのでしょうか?それともクライアントが別の場所に移動したのでしょうか? イベントソーシングの助けを借りて、この質問に答えることができました。 クライアントが移動した 、 固定 アドレスエラーの 2つのイベントがあります。
プロジェクション
当然、エンティティに関するすべての有用な情報はイベントのストリームに保存されるため、直接使用することはできません。 UIの場合、フラットモデル(プロジェクション)が必要です。これは、デノーマライザーと呼ばれるイベントハンドラーを使用して作成するだけです。 特徴的なプロパティは、そのようなハンドラーを好きなときに変更および追加できるという事実です。 プロジェクションはいつでも「破棄」でき、すべてのイベントを最初から再生して、新しいイベントを準備できます。 小さなコード例:
public void Consume (ShipArrived message) { readModel.Dock.Ships.Add(message.Ship); } public void Consume (ShipDeparted message) { readModel.Dock.Ships.Remove(message.Ship); }
もちろん、インターフェースの予測に加えて、イベント非正規化は、さまざまなレポートを作成し、イベントソースエンティティを分析するための強力なツールです。
プロセス指向のUI
メインデータウェアハウス(Truthのソース)をテーブル内の正規化されたデータに置き換え、それらに対するイベントレコードを使用したCRUD操作により、設計アプローチの変更が推進されます。 次のように、CRUDスタイルのイベントを持つことは有益ではありません。 その場合、セマンティクスおよび発生しているものに対するアタッチメントのすべての意味が失われます。 そのため、ユーザーがエンティティに対して小さなアトミックアクションを実行するようなインターフェイスを構築する必要があります。 つまり インターフェース設計は、データ入力ベースではなく、ワークフロー駆動型でなければなりません。
一般に、これは、ユーザーのアプリケーションでの作業を改善し、アクションを実行するときに複数ページの指示をプロンプトに置き換える傾向と一致します。 アプリケーション自体による学習。
技術的なポイント
このアプローチの技術的に興味深いユーティリティのカップル:
- 外部システムと統合すると、フィルター処理されたイベントのストリームを送信できます。 これにより、場合によってはタスクを簡素化できます。
- イベントストアは、非常に高速で拡張可能にできます。 イベントは変更されず、追加のみ可能です。
- 投影は地理的に複製できます。
問題
ご想像のとおり、それらは重要です。
リファクタリングの地獄
したがって、見よ、私たちのイベントは不変であり、そのフローは追加のみです。 うーん、それはどういう意味ですか? そしてこれは、一度起こったどんなイベントも永久に維持されなければならないことを意味します 。 元に戻すことも削除することもできません。 イベントの新しいバージョン、エラーを補正するイベントを作成できます。これらはすべて、既存のハンドラーに追加し、エンティティの使用チェーン全体で実行する必要がある新しいクラスと新しいクラスです。 プログラマーから間違いを犯す権利を得るのと同じであり、「ロールバック」計画はありません。 もちろん、これに同意しない限り、すべてのユーザーアクションを失って、イベントデータベースを前のスナップショットに戻すことは可能ですか?
いいえ、もちろん、私たちそれぞれが驚いて、ハンマー、パンチャーを取り、リポジトリで発生したイベントを変更することはできますが、これはおそらく、SQLデータベース内のデータの修正、データおよびインデックスファイルの修正に似ています。
要約すると、これは、イベントモデルを慎重に考え出し、描画する必要があることを意味します。ジュニア/ミドルをそこに行かせることはできません。 また、イベントが他のコンポーネントに送信される場合...一般に、外部イベントと内部イベントを区別し、それらの定義を別のリポジトリにロックする必要があります。 NuGetを介してのみリンクします。
準備ができていないツール
イベントソーシングを使用して開発を開始し、イベントを操作するためのすべてのツールを自分で作成する必要があるという事実に備えてください。 もちろん、Jonathan OliverのEventStoreがありますが、これはほんの一部です。 それらを管理するためのグラフィカルおよびソフトウェアインターフェイスが必要になります。閲覧と検索、投影の構築と更新、読書を最適化するためのスナップショットの作成など。
相互補償イベント
たとえば、ユーザーがニュースの購読を解除してから購読した場合、...と50回(年間を通じて)購読するとします。 その結果、署名またはサブスクライブ解除されている現在の状態のみが存在し、すべてが正常です。 ただし、このデータが使用される新しいレポートまたはプロジェクションを作成する必要がある場合は、そのようなイベントの処理に無駄な時間がかかりますが、マシンの負荷は高くなります。
サポート
イベントソーシングソリューションの保守は費用がかかり、困難です。 まず第一に、設計段階でのかなりの時間と、セマンティクスに準拠するために特定の種類の操作ごとに作成する必要がある多数の異なるイベントのためです。
結論
私の友人の一人が言ったように、「私たちは問題を解決するのではなく、自分たちにとってより快適な飛行機に移します。」 イベントソーシングについても説明できます。 特定の問題を解決するために彼が必要かどうかを誰もが判断する必要があります。
しかし、私は次のように言うことができます:よく研究されたエンティティにイベントソーシングを使用し、ポイント、その上にシステム全体を構築しようとしないでください。 これが最初ではないが、2番目の実装ではない場合があります。