SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

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

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

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

「ドメインイベント」クラスのモデリング

 続けて、イベントの情報を格納する「ドメインイベント」クラスの設計方法について見ていきましょう。イベントのモデリングを行う場合、イベント名やプロパティは「イベント発生元のコンテキスト」のユビキタス言語に従って検討します。集約のコマンドから発信されるイベントの場合、実行メソッドに準じたイベント名を使います。例えば、バックログアイテムの集約でスプリントにコミットした時のイベントであれば「BacklogItemComitted(バックログアイテムコミット時)」という名前を使用します。

 なお、集約のコマンドから発信する出来事ではなく、イベントそのものの業務的な意味合いが強い場合、イベントを集約としてモデリングする場合もあります。

ドメインイベントの共通項目

 IDDD本では、ドメインイベントの共通インターフェースにて2つのプロパティを定義しています。下図の通り「発生タイミング(OccurredOnプロパティ)」と「発生バージョン(EventVersionプロパティ)」です。これらの共通項目に加え、イベントごとの独自のプロパティとして、イベントの発生要因を示す情報を追加します。

イベントクラスの実装例(BacklogItemCommittedクラス)
イベントクラスの実装例(BacklogItemCommittedクラス)

 BacklogItemComittedクラスの場合、テナントとバックログアイテムとスプリントの識別子(ID)をプロパティとして設計します。イベントを受け取ったサブスクライバ側では識別子(ID)をキーに、変更内容を問い合わせて必要な制御を行います。

不変なドメインイベントクラス

 通常、ドメインイベントクラスは不変クラスとして設計されるため、コンストラクタではその値を設定することのみ可能で、プロパティは読み取り専用となります。

イベントの一意な識別子

 ドメインイベントクラスには「一意な識別子」は存在していませんが、イベントを使って外部のコンテキストと連携したり、メッセージ基盤を使ったりする場合には、一意な識別子が必要となる場合があります(一般的に、イベントの受信側は複数回イベントが送信されてくることを考慮し、「一意な識別子」を用いて重複排除を行います)。

基本的なイベント送受信方法

 続けて、基本的なイベントの連携方式を見ていきましょう。イベントの連携はパブリッシャー(出版側)と、サブスクライバ(購読側)による組み合わせで構成されます。

軽量なオブザーバーを用いたイベントの送受信

 IDDD本では、シンプルにイベントを送受信するには「軽量なオブザーバー」が良いとしています。オブザーバーとは、状態の変化を他のオブジェクトに通知するデザインパターンのひとつです。

軽量なオブザーバーを用いた基本的なイベントの流れ
軽量なオブザーバーを用いた基本的なイベントの流れ

 軽量なオブザーバーを用いて、イベントを処理する流れは次の通りです。

  1. [UIやWebサービス]:アプリケーションサービスのコマンドを呼び出す。
  2. [アプリケーションサービス]:イベント受信時に実行するサブスクライバをパブリッシャーに登録する。
  3. [アプリケーションサービス]:集約のコマンドを呼び出す。
  4. [集約]:ドメインイベントを生成する。
  5. [集約]:パブリッシャーを用いて、イベントを発信する。
  6. [パブリッシャー]:サブスクライバに対応するイベントの種類を確認して、イベントを配信(実行)する。
  7. [サブスクライバ]:自分が対応するイベントが配信されてきた場合は、イベントに適した処理を実行する。

 軽量なオブザーバーの特徴は、パブリッシャーとサブスクライバは同じプロセス/スレッドで動作し、イベントを発行した同じトランザクションにて処理される点です。

イベントを発信するパブリッシャー

 パブリッシャーは、サブスクライバにイベント通知を送る機能を提供します。IDDDのサンプルコードではDomainEventPublisher (JavaC#)というシステム共通のサービスとして提供されています。

イベントを受信するサブスクライバ

 サブスクライバは、イベント受信時に行う機能を提供します。例えば、メールを送ったり、イベントストア(後述)に情報を保存したりします。IDDDのサンプルではDomainEventSubscriber(JavaC#)というシステム共通のインターフェースを用いて、処理別にインターフェースを実装します。

 基本的なイベントの送受信の流れについては以上となります。

他システム(他の境界づけられたコンテキスト)とのイベント送受信

 続けて、他の境界づけられたコンテキストへ、イベントを送信する方法について見ていきましょう。リモートの境界づけられたコンテキストと連携するためには、ドメインモデルと外部システムにイベントを連携するメッセージ基盤との間で整合性を保つ必要があります。整合性の保ち方として主に3つの方法を紹介しています。

ドメインモデルとメッセージ基盤間での整合性を保つ方法
No. 概要 説明 メリット デメリット
1 共有データ領域 ドメインモデルとメッセージ基盤で同じデータ領域を使う ドメインモデルの変更とメッセージ基盤が同じトランザクションのため性能が良い メッセージ基盤のストレージをドメインと同じところに置くことが難しい
2 分散トランザクション ドメインモデルとメッセージ基盤が別のデータ領域を使うが整合性を保つために2フェーズコミットを使う ドメインモデルとメッセージ基盤でデータ領域を分離できる 分散トランザクションの仕組みが複雑、未対応のプロダクトも多い
3 イベントストア ドメインモデルとイベント用のストレージを同じデータ領域に用意する ドメインモデルが直接メッセージ基盤を使わないためシンプル イベントストアのイベントをメッセージ基盤に転送する仕組みが必要

 本稿では、IDDDとして特徴的な3番目のイベントストア方式を中心に紹介していきます。また、他の境界づけられたコンテキストと連携する仕組みとして、RESTで通知する方法と、メッセージングミドルウェア(RabbitMQ)で通知する方法を紹介します。

結果整合性と遅延の許容範囲

 なお、複数の境界づけられたコンテキストに連携する時には結果整合性が重要となります。非同期による遅延の許容範囲がどの程度であるかは、ドメインエキスパートに聞いて確認します。リアルタイム性が求められた場合は、現システムが導入される前は、どの程度の遅延が許容されていたのか確認してみるといいでしょう。

次のページ
イベントストアとは

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
IDDD本から理解するドメイン駆動設計連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 青木 淳夫(アオキ アツオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

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

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10392 2017/09/13 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング