SODA Engineering Blog
🤞

イベントストーミングを咀嚼する

2023/12/15に公開

\スニダンを開発しているSODA inc.の Advent Calendar 15日目の記事です!!!/

この記事は何?

11/10(金)にUMTP主催のModeling Forum 2023ワークショップ「ドメインモデリングの強力なツール: Event Stormingを体験しよう」に参加しました。

その内容を社内勉強会で共有したのですが、より血肉にしていくためブログ記事にしてみました。(今更)

ワークショップに参加しようと思った動機

前提として、現状、弊社はプロダクト開発をモノリス1リポジトリに対し、4チーム(1チームのBEえは4名前後)で開発をしています。

弊社では、今後IPO:1000億を目指す方針となっていて、その目標から逆算して、3年後160人ぐらいの開発組織になる見込みです。

流石に、現状のモノリスなアーキテクチャでは、その規模の開発組織を支えることはできないと判断しリアーキテクチャを検討しています。

そのリアーキテクチャの候補として、モジュラモノリス、マイクロサービスなどがあり、境界づけられたコンテキストを見つけ、そのコンテキストごと分割していくのが良さそうだという共通認識がある状態でした。

そのコンテキストを定義していくには、イベントストーミングなるものが良いと聞いたので、参加してきた次第です。

そもそも、ドメインモデリングとは?

ワークショップの表題のドメインモデリング、これは一体何なのでしょうか?

DDDの文脈で使われる言葉で、ドメインモデリングの言葉を形態素に分解すると、「ドメイン」と「モデリング」になると思います。

それぞれの定義がDDDリファレンスに記載があったので引用します。

domain: this is a sphere of knowledge, influence, or activity. the subject area to which the user applies a program is the domain of the software.

model: this is a system of abstractions that describes selected aspects of a domain and can be used to solve problems related to that domain.

DDDリファレンス より

上記の定義をもとに、ドメインモデリングを意訳すると、

「ドメインはソフトウェアが扱う特定の業務や活動の領域を指し、モデルは、そのドメイン内の問題を解決するために重要な側面を抽象的に表現すること」

になります。

ここでいう問題とは、何なのでしょうか?

問題とは、よく「現状」と「あるべき姿」のギャップで定義されます。

障害等の現状がマイナスなものを問題と思いがちですが、機能追加やリファクタリングも問題を解決する行為と捉えることができます。

例えば、決済手段を追加する等の機能追加を実施する場合、

「現状」は、新しい決済手段がつかえない、「あるべき姿」は、新しい決済手段が使えてUXが向上すると定義することができるので「問題」の枠組に入るかと思います。

こういった問題を解決していくために、モデルを定義することがドメインモデリングと言えるのかなと個人的に解釈しています。

ドメインモデリングの手法

そんなドメインモデリングには下記のようにいくつか手法があります。

  • RDRA(リレーションシップ駆動要件分析)
  • ICONIX
  • SUDOモデリング
  • イベントストーミング

イベントストーミングはその中の1手法になります。

イベントストーミングとは?

イベントストーミングとは、2012,3年頃にAlberto Brandolini氏が考案したモデリング手法です。ビジネスサイドと協働的にイベントを定義、発散させ、そこから徐々にモデルに落とし込んでいきます。

実際のセクションとしては、大きく分けて3つあります。

  1. ビックピクチャー
  2. プロセスモデリング
  3. ソフトウェアデザイン

それぞれのセクションで、細かい段取りがあるのですが、ビックピクチャーで一番最初にやることは「イベント」を思いつくままに付箋に書き出すことになります。

その次がイベントの精査(イベントではないものを除外する)を実施していきます。

それでは、イベントストーミングの名称にも含まれている、「イベント」とは何なのでしょうか?そもそも、なぜイベントに着目するとモデルに落とし込みやすくなるのでしょうか?

イベントとは?

eventとは、和訳すると「出来事」になります。

そして、出来事(コト)には、ヒトとモノが紐づきます。

例えば、弊社のコトを時系列順に例として上げると、

  • 出品者が商品を出品する
  • 購入者が商品を注文する
  • 購入者が商品代金を決済する
  • 出品者が商品をスニダンベースに発送する
  • 鑑定士が商品を鑑定する
  • ロジスティクスチームが商品を購入者に発送する

などがあります。

(実際にはもっと細かく多くのコトがありますが、省略しています。)

見て分かる通り、コトには前後関係があり基本ユニークですが、モノやヒトは複数のコトで登場しています。

コトを中心に業務アプリケーションが何をすべきかを整理していくと、その事象に関係するヒトやモノについても範囲を限定でき、関係も把握しやすいのです。
現場で役立つシステム設計の原則 | 増田 亨

と記載のある通り、コトに着目すると範囲を限定できることが良いと思います。範囲を限定した結果、目的に沿ったモデルを定義しやすいことが想像できます。

ヒトやモノに注目すると発散しがちです。ヒトに関連するデータと業務ロジックをすべて調べ上げるのは簡単な作業ではありません。モノについても同様です。モノを表示する属性は多岐にわたります。その属性を調べ上げても、なかなか業務の要点は見えてきません。
現場で役立つシステム設計の原則 | 増田 亨

とのことで、ヒトやモノから、モデルを定義しようと思うと、複数のコト(コンテキスト)の情報を整理する必要があり、難易度が高そうです。

また、ヒトやモノに注目したモデリングすると、複数のコンテキストにまたがった巨大なモデルが出来上がってしまう可能性もあります。

上記の例でいうと、下記の要素が商品モデルに混入する可能性があります。

  • スニダンベースへの発送
  • 決済
  • 鑑定通過
  • スニダンベースからの発送

リアーキテクチャを検討している現状でいうと、あまり良い状態とは言えなさそうです。

イベントかどうかを見極める方法

実際に、ビックピクチャーでイベント(コト)を定義するときに、それが「イベントかどうか」を見極めるにはどうしたら良いでしょうか?

見極めるための簡易的な方法としては、「〇〇する」という動詞句を追加するとリソース(モノ)かイベント(コト)かを識別できます。
T字形ER データベース設計技法 | 佐藤 正美

「配属する」は意味が通るので、配属はイベントとして扱えますが、「部署する」は意味が通らないので、部署はリソースとなります。

もっと厳密な方法としては、「タイムタンプが採取できること」、もしくは監査証跡が保管されていることもイベントとして定義することができます。
T字形ER データベース設計技法 | 佐藤 正美

とも記載してあるので、既存システムに対して、イベントストーミングを実施する場合、DBへのCreate, Update, Deleteをしていた場合、それはイベントとして扱って良いのではないかと考えています。

また、一般的にはそういった何かしらの更新の前に「~を確認する」などのバリデーションを行うと思いますが、それらの行為では一般的にタイムスタンプを採取していないのでイベントではないと定義できると思っています。

※当日のワークショップで講師の方々が名言はしていなかったはずなので、自分の解釈です。

イベントストーミング詳細

イベントストーミングでは8種類の付箋を使い分け、各セクションで貼ったり移動したりしながら実施します。

各付箋ごとの関係図は下記になります。

クレジットカードで商品を購入するときのフローが仮に下記だとする場合、

  1. 決済データをDB上に書き込む
  2. 決済代行会社に通信し与信を確保する
  3. 与信が確保できた場合、商品の人気ランキングを更新する

付箋で表現すると下記になります。

見て分かるとおり、コマンドはアクターかポリシーから実行されませんし、コマンドとイベントの間には集約か外部システムが必ず入ります。タイムラインは左から右に記載していくと良いとのことだったので合わせています。

実際のシステムはこんなに単純ではないので、下記の手順に則って各付箋ごとに作業して完成を目指していきます。

■ビックピクチャー

  1. 思いつくままイベントを張り出す(ダブりOK)
  2. イベントを精査
    • 似てるものを集め、グルーピング
    • 確認や、閲覧するはドメインイベントではないので除外する
  3. イベントを左から右へ時系列に並べる
  4. イベントを左から説明しながら、流れがおかしなところにイベントを補う
    1. イベントが足りなければ追加する
  5. 重要なイベントにフェーズを入れる。
    • ワークショップでは未実施でした。

■プロセスモデリング

  1. イベントの前にコマンドとアクターを足す
    1. イベントは過去形、コマンドは現在系で表現する
    2. イベントとコマンドは基本1対1の関係
  2. システムが自動化するコマンドをポリシーに変更する
    1. コマンドは、アクターかポリシーによる実行しかない
  3. アクターの前にリードモデルを追加する
  4. 外部システムを追加する
    1. 決済代行会社への通信など

ソフトウェアデザイン

  1. 集約を定義する
    1. コマンドとイベントを時系列順に上から並び替える
      1. 項番9で作った図から付箋をコピーして持ってくる
      2. モデルのfieldを書き出していくと、集約が定義しやすい
    2. それぞれ、集約を決めていく。
      1. 1イベント1集約になることもあるし、複数イベントで1集約になることもある。
  2. 境界を定義する
    1. ワークショップでは名言してなかったが、基本的に1集約1コンテキストで良さそう。
    2. 各コンテキストを枠線で囲み、システムを連携していく

※集約について補足

ソフトウェアデザインで「集約を定義する」とありますが、集約とは何なのでしょうか?

そもそも、集約とはドメインオブジェクトの集合帯で、2つのルールがあります。

ルールは以下の 2 つがあります。

  • 強い整合性確保が必要なものを 1 つの集約にする
  • トランザクションを必ず 1 つにする
    ドメイン駆動設計 モデリング/実装ガイド | little-hands

名言されていませんが、イベントストーミング上で定義する集約は集約ルートと認識しています。集約ルートには、下記のように他のオブジェクトが紐づくこともあります。

イベントストーミングの枠組みでは明示的に定義されていませんが、実装に入る前に改めて、ドメインモデルを図にしておくとチームの認識を揃えられるので良いのではないかなと思っています。

現状、弊社のDDDが導入される前の初期の実装は集約のことを何も考えずに、一旦同一トランザクションにぶっ込んでることが多いです。既存システムでのイベントストーミング実施後は、トランザクションの範囲が細かく分離されるのではないかと予想しています。

実際に所属チームで実施してみた感想

ワークショップだけでなく、現状、所属チームでもリアーキテクチャに向けてイベントストーミングを実施しており、ソフトウェアデザインの集約の定義をしている最中になります。

購入周りに絞ってイベントストーミングしてみたのですが、20個ほどのイベントが確認でき、集約の定義がとても大変そうです。

既存のイベントの話をしているときに、集約を別にしたほうが良いのではないか?という話が出てきたりして、良い議論が出来つつあるなと思います。

唯一のデメリットとしては、ある程度の時間が必要なことかなと思います。慣れてないこともありますが、購入という1領域に対し、ビックピクチャー、プロセスモデリングだけでも4人で4h程度はかかりました。ここから更に集約を決めていくとなるともう数時間程度はかかるかもしれません。

巨大なモノリスなので、他の領域にも手をのばすとなるともっと時間がかかると思います。

ただ、やりきった後は下記のようなメリットがあると思っています。

  • ドメイン知識の属人性が排除できる。
    • 新メンバーのキャッチアップコストが下がる
    • 退職時のドメイン知識の引き継ぎコストが下がる
  • 結果として、最終的な移行コストが少なくなる可能性が高い
    • 一般的に、抽象度の高いタスクを進めるときに仮説を立てると良いとされています。
    • 境界づけられたコンテキストまで分割できると、それがリアーキテクチャ時の仮のゴール(仮説)となります。
    • ゴールがない(仮でもコンテキストが定義できていない)状態で、リアーキテクチャを進めると、手戻りが多くなることが予想できます。
  • リアーキ後のシステム移行後の連携箇所が可視化される。
    • 3年後ぐらいには、マイクロサービスしかり、モジュラモノリスの場合でも、疎結合なシステムが複雑に連携し合っているはずです。
    • イベントストーミングを実施しておくと、その複雑さを表現する地図となり、改修時の影響範囲がわかりやすくなるはずです。

実際のメリット感についは、適宜振り返ってみたいですね。

イベントストーミングとアーキテクチャ

イベントストーミングのソフトウェアデザインまで完了した後、実際にアーキテクチャの設計に写っていくと思うのですが、どのようなアーキテクチャと相性が良いのでしょうか?

結論として、CQRS + イベントソーシングの構成が最大限効果を発揮するとのことでした。

ただし、CRUDな作り(ステートソーシング)だとしてもだ、イベントストーミングの結果とシステムが一致するコードとなるので、メンテナンス性はあがるとも仰っていました。
ワークショップの最後に、CRUDなステートソーシングな作りだった場合の実装を披露していただいのですが、確かにわかりやすかったです。

弊社の内部的な話ですが、一部のtableにstatusが20個ほどある場合があり、たまになぜそのステータスになったのかがすぐに分からないことがあります。
こういう場面に出くわすと、なるだけステートソーシングではなくイベントソーシングに寄せていったほうが良さそうに見えます。

イベントソーシングについては、まだ咀嚼しきれていないので別の記事で記載していきます。

最後に

まだ、先の話ですがリアーキテクチャを進めていった結果、どういうシステム構成になるのか楽しみです!

SODA Engineering Blog
SODA Engineering Blog

Discussion