SODA Engineering Blog
🐡

イベントストーミングを実施して、3日間で境界づけられたコンテキストを定義した話

2024/04/04に公開

この記事は何?

2024/3/5~2024/3/7にAWS ソリューションアーキテクトの福井さん、金森さんの助力を得てイベントストーミングを実施しました。

そのイベントストーミングでどういうことを実施して、どういう成果が出たのか、得た知見や学びについて書いていきます。

背景

前提として、弊社のバックエンドのアプリケーションの構成としては、いわゆるモノリスな構成となっております。2018年の創業からsnkrdunkの成長に合わせて、アプリケーションもイケイケドンドンと実装が追加され成長していきました。2022年ごろにはグローバル向けのアプリも提供し始めました。

その勢いのままに弊社はさらに事業を成長させ、時価総額1,000億規模のIPOを実現しようとしています。

IPOを目指すにあたって、システムでは大きな問題が2つあります。

  • 機能開発の速度が低下しつつある
  • JP側で開発した機能をGE側で再開発する必要がある(JP側とGE側が独立して開発を進めているため)

「機能開発の速度が低下しつつある」に至っては、厳密に定量的な評価ができているわけではないのですが、モノリスな構成で機能開発をしていることもあり、過去に作った機能への考慮で徐々に時間がかかるようになってきているという共通認識があります。

さらに、グローバル向けのバックエンドの機能(以降、GE)が日本のアプリケーション(以降、JP)とは別で作られていることもあり、同じ機能を実装するには2倍の工数がかかります。

この問題を解決するためにリアーキテクチャを推進しています。

イベントストーミングの検討とサポート依頼

リアーキテクチャを推進するにあたって、境界づけられたコンテキストを定義し、各コンテキストを高凝集、疎結合にしていくというのがリアーキテクチャの大枠の方針として決まっていました。

そのコンテキストを定義するために、イベントストーミングを実施したら良いのではないかという話は以前から出ていて、特定の領域をチームのエンジニアだけで実施していましたが、集約の定義が難しく適切な命名やコンテキストの範囲が見つからないでいました。

なんとなくエンジニアだけで進めるものではないような認識はあったものの、どう進めたらよいかは分からず迷走していました。

今回、偶然にも株式会社MonotaRO様の下記の記事を拝見し、
https://tech-blog.monotaro.com/entry/2024/02/01/090000

AWSのソリューションアーキテクトの福井さん、金森さんにサポート頂きながらドメインモデリングを愚直に進めていきました。

担当のSAの方に弊社もサポートしていただけないかと相談してみたところ、快くお受けくださりました。

イベントストーミング事前準備

イベントストーミングを実施するにあたって、福井さん、金森さんにアドバイスを頂き、各領域のドメインエキスパートを交えてオフラインで実施することなりました。

ここでいう、ドメインエキスパートの定義としては、ビジネス要件のASISとTOBEを把握している人になります。ASIS TOBEをもっと具体的にいうと、現場のフローや課題感を把握し、あるべき姿が描ける人になります。

各部署とこの要件で調整し、合計17名での参加となりました。

  • CS: 2名
  • logistics: 4名
  • Drop(持ち込み専門店): 1名
  • 鑑定: 1名
  • PdM: 2名
  • エンジニア: 7名

参加人数については、理想は10名で最大20名ぐらいまでが良いとのことでした。やはり人数が多すぎると議論が発散しすぎてまとまりにくいとのことです。

開催をオフラインにするかオンラインにするかにいたっては、当初のイメージだとmiroやfigjam等のツールを使ってオンラインで実施するものと思っていたのですが、物理的に顔合わせて実施したほうが早く終るとのことでしたので、今回はオフライン開催を選択しました。

考えてみたら当たり前かもしれませんが、オンラインだと並行して会話することができないので進行が遅くなるとのことでした。

開催場所は、弊社のオフィスや倉庫、会議室を借りることを検討したのですが、20名が入れる会議室を用意することがなかなか難しかったので、今回AWSの目黒オフィスを一部お借りして実施することとなりました。

タイムライン

タイムラインとしては下記です。

3/5

  • 10:00 福井さんから挨拶
  • 10:15 SODA CTO 林から目的の共有
  • 10:30 SODAにおける課題確認
  • 10:40 イベントストーミングの説明
  • 11:00 BigPicture開始
  • 15:00 Process Modeling開始
  • 17:00 ラップアップ

3/6

  • 10:00 Process Modeling
  • 17:00 Software Design

3/7

  • 10:00 Software Design
  • 17:00 ラップアップ

ファシリテーションは3日間、福井さん、金森さんが担当してくださいました。

SODAにおける課題確認

ドメインエキスパート含め話し合い、下記のような課題が出てきました。

  • システムがツギハギになっているので認知負荷が高い
    • →エンジニアがコードを読んでもドメインが理解しづらい
      • →結果として、思ったより開発に時間がかかる
  • SODAの業務全体が複雑になってきていて、業務が理解しづらい(新しい人は特に)

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

実施したセクションは大きく分けて下記の3つです。

  • Big Picture
  • Process Modeling
  • Software Design

Big Picture

1. Eventの洗い出し

ここでいうEventとは、各領域で行っている業務だったり、ユーザー行動が該当し、過去形の動詞でオレンジの付箋に書き出していきます。

例えば、「商品を購入した」とか、「商品を鑑定した」とかになります。

洗い出す前に、スタートとゴールをまずは決めました。

  • スタート
    • 商品登録
  • ゴール
    • スニダンベースからユーザーへ商品を発送する

後で分かるのですが、実際のスタートは商品登録ではなかったです。

後述するProcess Modeling中にイベントを商品登録よりも前のイベントを追加することが多々あったので、スタートやゴールは仮で問題ないと思います。

スタートを一番左、ゴールを一番右に置き、その間を左から右で時系列になるように、Eventを書き出して埋めていきました。次のセクションで時系列を並び替えるので、この時点だとなんとなくの時系列に張り出していきました。

2. 時系列について並び替える

ファシリテーターがドメインエキスパートへEventを掘り下げるような問いかけを実施し、時系列順に整理していきました。

掘り下げ方としては、

  • このEventはどういうときに、どういう目的で発生するのか
  • この言葉の意味は何なのか
  • 表記ゆれで違う言葉で定義されたEventが本質的には同じかどうか

などが多かったように思います。

同じ言葉で定義されてたり、本質的に一緒なものはイベント名を修正し、1枚に重ねて貼っていました。

同じEvent名で定義されていだけど、記載者によって文脈が違うケースもありました。その場合は文脈を記載し、一旦別イベントとして定義しなおしていました。

一つ前のセクションでGEのEventについても追加していたのですが、時間の都合上、このタイミングで一旦除外されました。

3. Pivotal Event (分割点になるEvent )をマーク

イベントの中で後戻りが難しいラインに縦線を引きます。縦線を引いたEventがコンテキスト境界になる可能性が高いためです。後述するスイムレーンも同様の理由で実施します。

前提として、弊社の購入フローはざっくりと、

出品者にスニダンベースに商品を発送して頂き、スニダンベースで鑑定し、購入者にスニダンベースから商品を発送する流れになっております。

このフローから出てきたEventとして、

「スニダンベースで商品を受け取った」や、「スニダンベースから購入者へ商品を発送した」などがあるのですが、これらのEventにマークが引かれました。

考え方としては、お金やモノが動くところを観点としてみていくと良さそうでした。

4. スイムレーン(並行処理、分岐点) の発見

並列で実行されたり、途中で分岐するビジネスフローを見つけ、横線を引いていきます。

ここでは、一次流通と二次流通のフローにスイムレーンが引かれました。

二次流通はいわゆるCtoCになり、スニダン側で在庫は持っていません。

一次流通とは弊社ではHypeDropなどが該当します。二次流通とは違い、スニダンで在庫を持ち販売まで実施しています。

それぞれ、商品登録のフロー、スニダンベース内でのロケーション管理も違うため、横線が引かれました。

5. 関係者/外部システムを洗い出し

ビジネスに関連する人や外部システムを洗い出します。

人は黄色、システムはピンク色の付箋に書き出し、該当Event周辺に貼り付けました。

人と言いつつ、部署やチームで表現したり、外部委託業者で表現するパターンもありました。

6. ナレーション/ウォークスルー

5まで実施した後に、左から読み上げてみて、曖昧なところがないか検証する作業です。

実際に読み上げていく最中に、Eventが追加されることがありました。

ここまで完了すると、下記のような付箋の状態になります。


※ショッキングピンクの付箋はProcess Modelingのセクションでも登場するHotSpotです。

Hot Spotは後で議論したいポイントなどを記載して残しておきます。

Process Modeling

Big Pictureで洗い出したEventに対し肉付け作業をしていきます。

下記の図に則って、User, Read Model, Command, Policy, Systemの付箋を貼り、ビジネスプロセスを明示的にしていきます。

https://www.slideshare.net/ziobrando/software-design-as-a-cooperative-game-with-eventstorming/27

それぞれの付箋に何を記載すべきか

Commandは何らかの意思決定を表現していて、「~する」などの現在形で記載します。

SystemはProcess Modelingでは特に何も記入せず、機械的にCommandの後に置いてきます。
(※イベントストーミングの本来のやり方としては、Process ModelingでもSystemに命名していきます。ただ、福井さん、金森さんの経験則や一般的にも、次のセクションのSoftware Designで、Systemが集約に置き換えられることが多いこともあり未記入で進めます。)

Userには意思決定者を記載していきます。Big Pictureの「関係者/外部システムを洗い出し」で書き出したUserをそのまま引用します。

Policyは、Event発生後、自動的だったり、手動で別の意思決定が行われるときに表現します。

弊社の例でいうと「商品を購入した」というEventが発生した場合、Push通知やお知らせ、メールなどを送信しています。この場合「商品購入ポリシー」などと付箋に記載して「通知する」Commandとつなげていました。

ちなみに、Policyの名前はそこまで重要じゃないので「Event名から抽出した名詞+ポリシー」で定義することが多かったです。

Read ModelはUserが意思決定するときのサポートツールです。

購入する際の商品詳細画面などのアプリケーション画面がイメージとしては付きやすいと思いますが、スニダンではない外部メディアやExcelファイルなどもRead Modelとして定義することもありました。

当日の進め方

1日目は全員で同じ領域のビジネスプロセスをモデリングしていたのですが、2日目からは速度上げていくために、スニダンベースで商品受け取り以降と商品登録~出品で2チームに分担し進めていきました。

今回のProcess Modelingで実施したのは、時間の都合上「ハッピーパス」のみです。

「ハッピーパス」とは、ユーザーから見て、一番シンプルで簡単な道筋のことです。

弊社でいうと、

商品登録→商品を購入→出品者がスニダンベースに発送→受取→鑑定→鑑定通過→スニダンベースから商品を購入者に発送

の一連の正常なプロセスのことです。

ハッピーパスではないものとしては、例えば、

  • 「出品者が発送期限をn日超過した場合、取引キャンセル処理を実施する」
  • 「鑑定通過せず取引がキャンセルになった」

などが挙げられます。これらは今回は考慮していません。

コンテキストまで定まった後にPoCを進めていくことになると思うのですが、その段階で再度検証していくことになる想定です。

また、モデリングするビジネスプロセスとしては、現時点でシステム化の有無は問いませんでした。

例えば、先に記載した商品登録の前に別のチームがシステム化されてない営業活動や作業を実施していたのことも判明したので、そこのプロセスもモデリングしていきました。

このセクションが完了すると、下記のような付箋の並びになります。(一部抜粋)

Software Design

このセクションでは集約と境界づけられたコンテキストを定義していきます。

参加者

このセクションは、一般的にはエンジニアだけで推進できるらしいのですが、今回はドメインエキスパートにも何人か残っていただきました。

タイムラインとして、全員出席している2日目の終盤には、このセクションまでたどり着いていました。

後述する商品登録周りの集約の命名の議論に、ドメインエキスパートに参加していただいて、より良い議論ができている実感があったことが背景になります。

当日の進め方

前提として、集約の命名ルールとしては名詞にする必要があります。コンテキスト名も同様です。

スタートの位置から順にProcess Modelingで定義したCommandとEventを抽出し、間にSystemのピンクの付箋を貼りつけます。貼り付けた、いくつかのCommandとEventから良さそうな名詞を議論しながら決めていきます。

その後、いくつかの集約をまとめて一つのコンテキストとして定義していきます。

コンテキストの範囲としては、Big Pictureで定義したPivotal Eventやスイムレーンを参考にしつつ決めていきました。

実際に進めてみて感じた議論のポイントは、「違和感があるかどうか」でした。

どういうときに違和感を感じ、どういうプロセスで集約やコンテキストを定義したか、2つ事例をご紹介します。

事例: 商品カタログ

名詞には抽象度の高い、低いがあると思います。抽象度が高すぎると範囲(責務)が広すぎるし、低すぎると狭すぎます。ちょうど良い塩梅を見つけていく必要があります。

例えば、スタートの商品登録の集約名として、最初は「商品」が良いのではないかという話が出ていました。これはCommandやEventに「商品を登録する(した)」とか、「商品を公開する(した)」が含まれていたことに由来します。

そして、コンテキスト名も商品コンテキストとして定義されていました。

ただ、議論が進むにつれ、商品登録のプロセスには、ブランドやカテゴリ、モデル、タイプを登録するCommandも含まれていて、これらも商品コンテキストに含まれたほうが良さそうだという話になったときに商品コンテキストに違和感を感じていました。

また、商品コンテキストだと、抽象度が高すぎて、「商品を購入する(した)」というCommandも含まれそうで名詞の範囲が広すぎるのではないかという話も出てきました。

あーでもない、こーでもないと議論を進めていく中で、あるエンジニアから突発的に「商品カタログ」が良いのでは?という案が出てきて、それが採用されました。

このコンテキストはブレストのような形で集約やコンテキストが決まりました。

事例: 出品、一次在庫、販売品

他の例でいうと、弊社のASISでは1次流通品の在庫の追加を2次流通の出品機能を使って出品しています。

議論していく中で、

  • 一次流通は在庫を追加するとか、登録するがしっくりくる。
  • 出品コンテキストにまとめて定義するのは違和感がある

という話になりました。

そこから、出品コンテキストと一次在庫コンテキストを分ける話になりました。

ただ、購入するときのASISの仕様として、カート機能では一次在庫と二次流通の出品を気にせずまとめて買えるというものがあり、TOBEも同様でした。

なので、購入のコンテキストは一次在庫と出品をまとめて購入できるような仕組みが必要でそれに準じた命名が必要でした。

一番最初はそのまんまですが購入品という集約名で、購入コンテキストが良いのではという話でしたが、購入品という命名に違和感があり、ブレストした結果「販売品」という集約名になり販売コンテキストという名前になりました。

※定量的に違和感を検知する方法

目安として、1集約に6個以上のコマンドが存在すると、集約の範囲としては広すぎることが多いらしいので、違和感を定量的に判断する際にチェックしてみると良さそうとのことでした。

結果

下記のようなコンテキストマップになりました。

所感

まず、感謝を表したいのは、ソリューションアーキテクトである福井さんと金森さんです。お二方の適切なファシリテーションがなければ、3日間でここまでの進捗を出すことができなかったと思います。 
さらに、3日間通してサポートしていただいたソリューションアーキテクトの木村さん、林さん、営業の小野里さん、社内のドメインエキスパート、エンジニアへも心から感謝しています。皆さまの協力により、適切な議論ができ、最終的にコンテキスト境界を定義できました。

イベントストーミングを実施してみて、商品登録やlogistics周りのプロセスが思ったよりも複雑なことが理解できましたし、コード見ているだけでは見えてこないドメイン知識が多々有りました。

特に今回一番学びになったのは、ドメインエキスパートとASIS TOBEの両軸で議論したことです。

今の仕様に引っ張られすぎず、あるべき姿を踏まえたうえでビジネスプロセスを可視化したことで、より良いコンテキスト境界を定めることができました。

実は、1年ぐらい前からモジュール分割の話は出ていて、まずは境界づけられたコンテキストを定義しなきゃいけないという共通認識はありました。この1年間ぐらい機能開発の片手間にエンジニアだけで境界を定義したり、イベントストーミングをコードベースでチームのエンジニアだけで閉じて実施してみたり、だいぶ手探りで進めてきました。

ビジネスプロセスとシステムを揃えることがDDDの本質的な思想としてあると思うのですが、あのままエンジニアだけでモジュール分割を推進していたら本質からずれた結果になっていたと思います。良きタイミングで実施することができて幸いでした。

一応、この記事にどういう観点でイベントストーミングを進めたか、すべて書き起こしたつもりではあるので、同じようにモジュール分割を推進しようとしている人の参考になれば幸いです。
また、自分たちだけで進めることが難しいのであれば、ぜひお近くの有識者に相談してみると良い方向に進むのかなと思います。今回特にそれを実感しました。

SODA Engineering Blog
SODA Engineering Blog

Discussion