こんにちは。テックリードの友野です。最近、急に寒くなったもので、衣替えが追いついていません。
さて、11/10(金)にUMTP主催のModeling Forum 2023ワークショップ「ドメインモデリングの強力なツール: Event Stormingを体験しよう」に参加してきたので感想と、メモの整理を兼ねてポストします。
ドメインイベントの伝播による整合性担保やその仕組みはContractS CLMで部分的に採用していますが、その領域はごくわずかです。イベントストーミングという言葉そのものは知っていましたが、業務では採用しておらず、経験もありません。今回のワークショップを通じて、多くの学びがありました。
(2023/11/15 追記:UMTP事務局よりmiroキャプチャ利用許可をいただいたので、画像を追加しました)
ワークショップ概要
ワークショップは、イベントストーミングを体験し、慣れることを目的としています。
1チーム4~6人で構成し、イベントストーミングのプロセスに沿って議論しながらmiro上でモデリングをしました。テーマは図書館業務。誰もが知っている/利用したことがある一方で、その業務についてすべてを理解している人はいないことが理由だそうです。図書館司書と利用者、2つのアクターそれぞれの業務を参加者全員(30人!)で分担して整理しました。
具体的には、書籍"Learning Domain Driven Design”(以下、LDDD)で紹介されているステップに沿って(一部省略して)進めていく形式です。ステップバイステップで進めていく中で生まれた疑問点や不明点を都度、講師(Chatwork加藤さん/GMOインターネット成瀬さん)に聞けるという贅沢な時間でした。
イベントストーミングとは
イベントストーミングはブレインストーミングのドメインイベント版です。つまり、イベントをとにかく発散させて徐々に収束させていくドメインモデリングの手法です。このアプローチは、ドメイン上の重要な関心ごとであるイベント=出来事(コト)に着目しています。
イベントに着目する理由として、以下があります。
- イベントが分かれば、そのイベントを生み出したふるまいが分かる
- イベントはヒトやモノと必ず関係があり、コンテキストがあるので収束させやすい
- 逆にモノからアプローチすると、複数コンテキストがある場合があり、発散させやすい
イベントストーミングはビッグピクチャー、プロセスモデリング、ソフトウェアデザインから構成されます*1。参加者の知見や認識を揃えながら、業務の流れを整理したいシーンにはフィットしそうです。
進め方
1. イベントを整理する(ビッグピクチャー)
ワークショップでは、まず以下の流れでイベントを整理しました。
- イベントを書き出す
- イベントは出来事なので動詞の過去分詞形で表現し、この段階では他者との重複は気にしない。
- 例:
利用者を登録した
、蔵書を貸し出した
- 例:
- イベントは出来事なので動詞の過去分詞形で表現し、この段階では他者との重複は気にしない。
- イベントを精査する
- イベントを左から右へ時系列に並べる
- 同時に起きるイベントは縦に並べる
- 時系列を順に読み合わせて矛盾がないか確認する(ウォークスルー)
- 例えば、登録していない情報を突然更新していないか など
- 足りなければ、この段階でイベントを追加する
※ LDDDに記載されているフェーズ
については、ワークショップではスキップしました。
イベントストーミングでは議論が白熱したり、横道に外れたりした場合は、ホットスポットとしてメモを残して議論を先へ進めます。例えば、「発注した本の支払い方法は銀行振り込みかクレジットカード払いか」という論点は図書館業務の整理から見れば、ホットスポットです。
2. イベントからプロセスの流れを見つける(プロセスモデリング)
コマンドとアクター/ポリシーをつなげる
イベントが揃ったら次は、そのイベントを生み出すふるまいの整理です。
- イベントからコマンドを作る
- コマンドはリクエストなので動詞の現在形(命令形)として表現する。日本語の場合、体言止めは分かりにくいので非推奨とのこと。
蔵書を貸し出した
(イベント)→蔵書を貸し出す
(コマンド)
- コマンドをリクエストするアクターを配置する
- システムが自動的/連鎖的にリクエストする場合はポリシー
- ポリシーは次のコマンドをリクエストするトリガーのようなもの
- ポリシーの例:
本を入荷した
(イベント)->管理番号採番ルール
(ポリシー)->管理番号を採番する
(コマンド)
コマンドを実行するためのリードモデルを定義する
コマンドを実行するために何かしら情報が必要であり、この情報こそがリードモデルです。システム外のリードモデルも表現しておくのが肝です。
- リードモデルを追加する
- 複数のリードモデルからコマンドを実行する場合もある
- 例えば、
蔵書を貸し出す
(コマンド)ために、蔵書
(リードモデル)と貸出状況
(リードモデル)が必要
- 例えば、
- 複数のリードモデルからコマンドを実行する場合もある
- どのイベントからリードモデルが作られるのかを紐づける
蔵書を貸し出した
(イベント)後に、貸出状況
(リードモデル)が更新される
- システム外のリードモデルも表現しておく
- 利用者登録時の身分証明書 など
外部システムを追加する
モデリング対象の業務とは直接関係のない外部システムがある場合は、議論の発散を避けるため明示するだけに留めます。
3. コマンドとイベントから集約を見つける(ソフトウェアデザイン)
最後に一連の流れを俯瞰してみて、コマンドを受け取り、処理結果としてイベントを生み出す集約を見つけます。
当たり前ですが、このステップは機械的には出来ず、コマンドとイベントからどのような概念があるのか議論が必要です。イベントストーミングを用いない、ヒアリング中心のドメインモデリングでも変わらず難しいステップです。集約は名詞で表現するのが一般的なので、その命名に相応しい責務なのか、分割/統合するならライフサイクルは適切かという観点が重要です。
感想
終日議論をし続けて、疲労感と充実感で満たされたワークショップでした。イベントストーミング初体験でしたが、良い点と注意点が見えてきました。
良い点
議論を進めやすい
モデリングするフレームワークなので当たり前と言えば当たり前ですが、ステップバイステップで参加者の意識・興味を集中できるので、議論が進めやすく感じました。ワークショップの同じチームメンバーとは初対面、かつ図書館業務経験者(ドメインエキスパート)不在でしたが、適度な発散と収束を繰り返しながら、メンバー全員が納得いく集約の定義まで時間内に進めることができました。
集約検討時に前提の認識を揃えやすい
一つ目と似たような観点ではありますが、イベントに着目した業務の流れを参加者全員で作り上げていくため、いざ集約の議論を始めようとするとそこまでの知識が揃った状態で始められます。場合により、発散させたいケースもあるかもしれませんが、こと問題領域を明らかにしたいケースにおいて、参加者の認識が揃った状態で議論が開始できるのはとても強力です。
要求の曖昧さを排除できる
イベントが時系列に並び、ウォークスルーで整合性を担保できるので、ユースケースの確からしさを検証できます。ContractSでは予備設計としてロバストネス分析を一部領域に採用していますが、近しいものを感じました。繰り返し実施することで曖昧さを排除し、不確実性を減らしながら価値検証するアプローチにフィットしそうです。
注意点
効果を最大化するためにはアーキテクチャの制約がある
注意が必要なのは、イベントストーミングの効果を最大化するためにはCQRS(Command-Query Responsibility Segregation)+イベントソーシングの構成が前提となっている点です。
ふるまいの結果として生み出されたドメインイベントが記録され、そのイベントからリードモデルが作られる前提のため、CQRSのようにモデルレベルで分離した構成が必要ですし、何よりイベントを記録していくためにイベントソーシングを採用していないと、イベントをイベントのまま永続化できません。
ワークショップでは成瀬さんがステートソーシングによる実装方式をライブコーディングしてくれましたが、コードからイベントの知識は消えているので、いずれモデルとコードに乖離が発生してアジリティを失う懸念があります。
逆に言えば、CQRS+イベントソーシングの構成であれば、これほど強力なモデリングフレームワークはないとも思います。
終わりに
初体験のイベントストーミングでしたが、とても興味深いものでした。適用するにはアーキテクチャ観点で若干のハードルがあるものの、エンジニア職以外のメンバーと共通言語で会話する最初の一歩として効果がありそうです。幸い、JavaにはAxon Frameworkというイベントソーシングをサポートするフレームワークがあるため、小さく検証することもできそうです。試した結果はまた別記事でまとめようと思います。
*1:必ずしもこれらのプロセスをしなければならない、というわけではないようです。