Shoeisha Technology Media

CodeZine(コードジン)

記事種別から探す

実践DDD本 第8章「ドメインイベント」~出来事を記録して活用~

IDDD本から理解するドメイン駆動設計 第8回

  • LINEで送る
  • このエントリーをはてなブックマークに追加

 ドメイン駆動設計(DDD)は、顧客と開発者が業務を戦略的に理解し、共通の言葉を用いてシステムを発展させていく設計手法です。前回は「ドメインサービス」について紹介しました。8回目となる今回は「ドメインイベント」について紹介します。

目次

ドメインイベントとは

 「ドメインイベント」は、ドメインで起こった出来事をモデリングする仕組みです。ドメインイベントを使うことで、複雑になりがちな出来事を管理し、システム間の連携を柔軟にすることができます。

 DDD本の発売後に発展してきた概念のため正式な定義は書かれていませんが、エヴァンス氏は

 ドメインイベントは、ドメインモデルの一部であり、ドメイン内で発生する何かの出来事を表す。

と述べており、出来事をモデリングする有用な手法と認識していることがわかります。

ドメインイベントのモデリング方法

 「エンティティ」や「値オブジェクト」ではオブジェクトの属性や振る舞いに対してモデリングを行ってきました。これに対して、ドメインイベントは「ドメインエキスパートが注目する出来事」にフォーカスします。具体的にはドメインエキスパートが話す「〜する時に」や「〜した場合」といったフレーズに注目します。

ドメインイベントの発見方法
ドメインイベントの発見方法

 また、イベントは「システム的な観点」から導入するケースもあります。例えば、特定のシステムで発生した出来事を外部システムに通知する場合や、境界づけられた同じコンテキスト内のトランザクションを分離する場合などです。

ドメインイベントがもたらすメリット

 ドメインイベントには、結果整合性(結果として一貫性が保たれること)を用いたシステムの構築が容易となるメリットがあります。ドメインイベントを利用することで、密結合になりがちな他システムとの連携や、他の集約へのデータ反映を疎結合にできます。

バッチ処理に関する考え方の変化

 イベントの概念を導入すると「バッチプログラム」の設計も変わってきます。多くのシステムでは集計処理を行う夜間ジョブが動作しています。通常、前日の変更データを複雑なクエリーで取り出し、長いトランザクションを使って変換する処理を行っています。しかし、ドメインイベントを導入することで、発生したイベントは随時通知され、反映が必要なシステムを取り込むだけでよくなります。その結果、従来のバッチプログラムが不要になる場合があります。

集約の制約からの開放

 また、DDDの集約(10章)には「単一のトランザクションでは単一の集約の固まりだけを変更しなければいけない」という推奨ルールが存在しています。しかしモデリングをしていると、別の集約も更新したい出来事が発生することがあります。こうした場合にイベントを活用することで、トランザクションの範囲を広げることなく結果整合性を保てます。

 同様にリモートシステムにおいても、分散トランザクションを意識せずにすみます。その結果、スケーラブルでパフォーマンスに優れたサービスを構築しやすくなります。

ドメインイベントの導入

 イベントを導入していくには、ドメインエキスパートの「その結果どうなるのか」「いつ無視するべきか」といった業務的な観点からイベントの要否を判断します。次に「他システム連携は必要か」「イベントソーシングは必要か」などの技術的な観点からイベントの連携方式を検討します。

イベントを用いた処理の例

 SaaSOvasionのアジャイルプロジェクト管理コンテキストの場合「バックログアイテムがコミットされたら、コミット先のスプリントやその他の関係者たちに通知する」といった要件があります。この例をイベントを用いて制御する場合、次の流れとなります。

  1. 集約のコマンド「スプリントにバックログアイテムをコミットする」が呼び出される。
  2. 集約のコマンドで、コミットされた旨の「ドメインイベント」が生成される。
  3. 「ドメインイベントパブリッシャー」がイベントを発行(出版)する。
  4. 「サブスクライバ」がイベントを受信(購読)する。
  5. 「サブスクライバ」でメールを送信する。
イベントの発信と受信の流れ
イベントの発信と受信の流れ

 IDDDではイベントの発行を「パブリッシャー」で行い、イベントの受信を「サブスクライバ」で行います。

 サブスクライバが処理する内容としては、大きく次の3つの傾向があります。

(1)同期処理

 イベントに応じた処理を、イベント発行と同じトランザクションで実施します。サブスクライバで処理が完結します。

(2)イベント格納処理

 同一トランザクションではイベントの記録だけ行います。後述する「イベントストア」等を活用して、イベントに応じた処理は別途実行されます。

(3)分散処理

 イベントを他システムにリアルタイムで転送し、2フェーズコミットなどの「分散トランザクション」で制御を行います。この分散トランザクションの導入は製品固有の知識が必要なため、難易度が高くなる傾向にあります。

 簡単な処理の場合はサブスクライバのみで処理が完結しますが、外部システム連携が必要なイベントの場合はイベントストアや分散トランザクションの利用を検討する必要があります。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • WINGSプロジェクト 青木 淳夫 (株式会社ネクストスケープ)(アオキ アツオ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2017年5月時点での登録メンバは52名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂き...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:IDDD本から理解するドメイン駆動設計

もっと読む

All contents copyright © 2005-2017 Shoeisha Co., Ltd. All rights reserved. ver.1.5