Event Stormingワークショップを体験してきた話

:::note info
これは [ZOZO Advent Calendar 2024](https://qiita.com/advent-calendar/2024/zozo) カレンダー Vol.6 の 14日目の記事です
:::

## 1.はじめに
今回の記事では、先日参加した[MF2024ワークショップ②『Event Stormingワークショップ』](https://umtp-japan.org/event-seminar/74976)について、その内容や感想をまとめてみたいと思います。

本ワークショップは、UMTP様（[特定非営利活動法人UMLモデリング推進協議会](https://umtp-japan.org/)）が主催しているもので、講師は「[ドメイン駆動設計入門　ボトムアップでわかる！ドメイン駆動設計の基本](https://www.shoeisha.co.jp/book/detail/9784798150727)」の筆者である成瀬 允宣さんです。

本記事では、**ワークショップを通じて得た自身の学びや気づき、そしてイベントストーミングについての理解を深めるためにまとめた内容を共有したい**と思います。

## 2. ワークショップに参加しようと思ったきっかけ
現在、自分が所属しているチームでは、ZOZOTOWNを裏で支える基幹システム（ZOZOの社員やZOZOTOWN出店者様がバックオフィス業務の為に使うシステム全般）のリプレイスを推進しています。

基幹システムで扱う領域は多岐にわたり、ビジネスルールやデータ構造が複雑であるため、システムの設計や実装においては、ドメイン駆動設計（DDD）の考え方を取り入れています。

現状では、一部機能はマイクロサービス化を実施してサービスを分割し、新たなシステムを構築しています。

**参考：**[モノリスからマイクロサービスへ-ZOZOBASEを支える発送システムリプレイスの取り組み](https://techblog.zozo.com/entry/replacing-shipping-system-supporting-zozobase)

一方で、マイクロサービス化が現時点で難しい領域に関しては、まずは現行システムを整理し、モジュール境界を明確にすることに加えて、VB ScriptからJavaへの言語リプレイスを進めることを優先しています。

**参考：**[本番環境における等価比較を活用した言語リプレイス](https://techblog.zozo.com/entry/language-replacement-equality-comparison)

上記のように、各領域でシステムのリプレイスを進める中で、**ビジネス要求を整理し、システムの設計に活かすための手法**を体系的に学びたいと考えていました。

その折、UMTP様が主催するイベントストーミングワークショップを知り、今回参加することにしました。

## 3.イベントストーミングとは
ワークショップに参加する前は、イベントストーミングについてほとんど知見がなかった為、事前に調べた上で参加しました。

### 3.1.イベントストーミングとは
> イベントストーミングの大きな利点の1つは、参加者間での「ユビキタス言語」の形成を促進することです。  
> イベントストーミングを通じて、ドメインエキスパートの深い洞察や知識が明確に表現され、IT専門家と共有されることで、より豊かなドメインモデルの構築が促されます。  
> ［入門］ドメイン駆動設計 ――基礎と実践・クリーンアーキテクチャ 2-3 イベントストーミング |技術評論社

### 3.2.イベントストーミング 3つのプロセス
> ビックピクチャー：ドメイン内で発生する様々なイベントを洗い出し、時系列に沿って並べていくプロセス  
> 
> ビジネスプロセスモデリング：イベント同士を具体的に関連づけていくプロセス  
> 
> ソフトウェアモデリング：ソフトウェアの設計に移る、集約の深掘りや境界づけられたコンテキストの特定、ドメインモデルをソフトウェアに落とし込むプロセス  
> 
> ［入門］ドメイン駆動設計 ――基礎と実践・クリーンアーキテクチャ 2-3 イベントストーミング |技術評論社

上記を頭に入れた上で、参加前は「ふむふむ、イベント駆動でドメインイベントを整理する手法なのね！（あとは何もわからん）」という理解でした。

**SUDOモデリングを使ってのドメインモデリングは経験があるのですが、ドメインイベント起点で整理するのは初めてで、どのような流れで進めるのか、どのような成果物が得られるのか**、参加前から楽しみでした。

## 4. 図書館でイベントストーミング：イベントストーミングをやってみた
ここからは当日のワークショップでの内容と学びを共有します。

今回のワークショップのテーマは「**図書館**」で、図書館の業務プロセスをイベントストーミングで整理していきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/cbbbddd4-7fd6-ceb5-c717-a7c3b7c439f0.png)


各チーム3-4人単位でチームに分かれて、ツールとしては、オンラインボードツールの「Miro」を使用しながら、それぞれのチームでイベントストーミングを進めていきました。

**1日かけてのイベントストーミングでしたが、本当にあっという間に時間が過ぎていきました**

### 4.1. ビックピクチャー
ワークショップの冒頭では、ビックピクチャーを描くプロセスからスタートしました。 ビックピクチャーの手順とポイントは以下です。  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/5c2d80a3-4ba8-0988-5c3b-92a25fd1f10d.png)


#### 1. イベントの書き出し
- 図書館で想定されるあらゆるイベントを洗い出します。
- **イベントは過去形で書く**、**タイムスタンプがつけられるものかどうか**が判断ポイント。
- まずは時系列関係なく、図書館で発生するイベントを思いつくままに書き出していきます。
- この段階では「**アイデアは評価しない**」：どんどん書き出すことが大切。
```
例：「本が返却された」、「本が貸し出された」、「本が紛失した」
タイムスタンプがつけられるものを挙げていく：2024年12月14日に本が返却された、など 
```

#### 2. イベントの分類
- イベントがある程度書き出されたら、イベントを分類します。
    - 今回は図書館の業務システムなので、 「**図書館側**」と「**利用者側**」のイベントに分類する。
    - 図書館側と利用者側に分類できたら、時系列で整理していく。

```
図書館側
- 本が貸し出された
- 本が返却された
- 本が紛失した

利用者側
- 本を予約した
- 本を借りた
- 本を返した
```

#### ブレーク：カラーパズル思考
ビックピクチャーでドメインイベントを出す時には**オレンジの付箋**を使っていたのですが、これには理由がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/d5cf765f-e478-0274-399d-acba095a5992.png)

> 参考：[イベントストーミング入門【ノーカット版】](https://www.youtube.com/watch?v=jC9lE4YqgyY)で紹介の図から引用

上記図は実際のイベントストーミングの際にも使用したのですが、この図を見てもらうとわかる通り、**オレンジの付箋**は**ドメインイベント**を表しています。

他にも、それぞれの対象には個別で色が割り当ててられていて、**ドメインイベントを整理する際にある程度機械的に進めることができるよう**になっています。

それぞれの付箋の役割を以下にまとめます。

##### 紫：ポリシー
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/4069a8f1-dcd2-c436-8fca-08c4b166ea41.png" width="200" height="100">

  - **イベントとコマンドを結びつける重要な要素**。
  - 特定のイベントが発生した際に、**必ず**または**自動的に**特定のコマンドが実行されるような規則を定義する。
  - **アクターの操作を仲介**せずに、他コマンドの実行を自動で表現する。

##### **青**： **コマンド**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/d4710d97-0385-9f14-0584-dbbe9365d86f.png" width="200" height="100">

  - **イベントを引き起こすためのキーとなる要素**。
  - 各イベントはそれ単独で発生するのではなく、**コマンドによって引き起こされる**。
  - コマンド = システムの操作・アクション　（例：「本を貸し出す」、「本を返却する」）。
  - 基本的には、**イベントの現在形を記述する**ことが多い（が、例外も多数あり）。

##### **薄やまぶき**： **集約（Aggregates）**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/739092c3-43b9-ce5e-bce4-da718d3bea5f.png" width="200" height="100">

  - **コマンドが操作可能なデータのまとまりを表現する**。
  - 一貫性を担保したいデータとロジックのまとまり、ビジネスルールをオブジェクトとしてカプセル化すること（システム的な表現）。
  - **コマンドを引き渡す相手であり、イベントを引き起こす当事者**。
  - 集約は名詞で表現することが多い（例：「貸出」集約、「予約」集約）。

##### **ピンク**： **外部システム**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/af1835e6-fe29-53b8-bb50-f59e898ebbcf.png" width="200" height="100">

- 外部のシステムを表現（例：外部のメール送信システム、決済システム、他チームが管轄するマイクロサービス）
  - **外部システムがコマンドを受けつけ、イベントを発行するもの**として表現する。

##### **黄色**： **アクター**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/26be032b-46f2-8085-52ce-e601d5cf34ba.png" width="200" height="100">

  - **コマンドを実行する人間のユーザーやシステムを表現**。
  - プロダクトを利用する人間や、他のシステムとのインタラクションを表現する（例：「図書館の利用者」、「図書館の管理者」）。

##### **ミント色**： **リードモデル（ReadModel）**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/6cf42743-6d4d-cc50-63d6-b23cabd98bca.png" width="200" height="100">

  - システム内でのデータの読み取りを表現。
  - システム内のデータモデルやメール、ダッシュボード等の様々なデータの読み取りを表現する。

##### ホットスポット
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/603d0572-a25d-a58f-5dc0-8530fb909200.png" width="200" height="100">

  - **留意点**を表現する。
  - 留意点をホットスポットに書き留めておき、後程議論する。
  - TODOやドメイン知識が記述される。

### 4.2. ビジネスプロセスモデリング
ビックピクチャー作成後は、ビジネスプロセスモデリングを実施しました。
**分類したドメインイベントを起点にして、イベント間の関係性を整理**していきます。

#### イベントとイベントを繋ぐ：イベントストーミングで使う図の理解
先ほども紹介した図を再掲します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/d5cf765f-e478-0274-399d-acba095a5992.png)
> 参考：[イベントストーミング入門【ノーカット版】](https://www.youtube.com/watch?v=jC9lE4YqgyY)で紹介の図から引用

上記図をベースにして、抽出したイベントを繋げていく作業を行いました。  

##### ルート1
`イベント →　ポリシー → コマンド → 集約 または 外部システム → イベント`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/721e227f-9538-cc9a-7438-91a757ded4c3.png)

ルート1については、**あるイベントが発生した際に、ポリシーが適用され、コマンドが発行・新たなイベントが発生する**というルートです。

今回のワークショップ内で、自分のチームは**図書館側**のユースケースを考えたのですが、その中の1つに「**損傷された本が返却されたケース**」がありました。

**【想定ユースケース】**：図書館の司書さんが損傷している本を見つけた場合

その時に作成した図が以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/6517f41d-2e42-8213-6af3-0dc52cb6b177.png)

#### 【イベントフロー】
1. （アクター）司書さんが（コマンド）損傷度合いを確認する。
2. （ドメインイベント1）本の損傷状態を**確認した**。
3. （ポリシー） **修復できない場合**：（コマンド）弁償通知を出す → （ドメインイベント2）弁償通知した。
4. （ポリシー） **修復できる場合**：（コマンド）修復を行う → （ドメインイベント3）書籍を修復した。

**※ 上記の例をどういうふうに管理システムで実現するか？の落とし込みまでは時間がなくできませんでした**

上記ユースケースにおいては、**ドメインイベント1**を契機に、ポリシーが適用されて**複数のドメインイベント**（2,3）が起きたことを図に表現しています。

##### ルート2
`イベント →　リードモデル（Read Model） → アクター → コマンド →　集約 または 外部システム → イベント`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/40dfb8f9-bda4-fb76-7cce-72504297055e.png)


ルート2は、**あるイベントが発生した際に、リードモデルが読み取り、リードモデルの結果を受けてアクターがコマンドを実行する**というルートです。

以下は、図書館側で新規利用者カードを作成した通知を行った際の図です。
**【想定ユースケース】**：図書館の管理者が利用者に対して利用カードの新規作成が終わった旨を伝える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/f0f5da55-5e3d-2e2f-b4b4-7edc8dd4e54c.png)

#### 【イベントフロー】
1. （アクター）管理者（コマンド）図書館利用カードの準備を完了する。
2. （ドメインイベント）図書館利用カード作成通知を**送信した**。
3. （リードモデル） 「メール通知」として利用者に伝達。
4. （アクター）利用者がメール通知を見てNEXTACTION。

ルート2.では、**あるドメインイベントを契機に、アクターがコマンドを実行する**という流れになります。

### 4.3. ソフトウェアモデリング
本来であれば、このタイミングで集約を考えるべきですが、ここまでの作業で時間がかかり、集約の作成まで行うことはできませんでした。

ただ、集約を考える上でのイベント図がこの段階で作成されているので、スムーズに集約の検討が進められるという印象を受けました。

今回学んだことを生かして、コードに落とし込む部分のところは自身で実践していこうと思います。

## 5. イベントストーミングを体験してみて
今回のワークショップを通じての感想は以下になります。

- カラーパズル思考を使ったイベントストーミングは、**ドメインイベントを整理する上で非常に効果的**。
  - 今回は図書館の業務プロセスを整理しましたが、他の業務プロセスにも応用できる手法だと実感。
  - 普段の業務でも、リプレイス対象のユースケースがあった際に、SUDOモデリングだけではなく、ドメインイベント起点で整理することを意識していきたい。
　　
- **ある程度のDDDの知識は必要だと実感。**
  - ビックピクチャーぐらいに関しては、システム設計の経験がなくても取り組めそう。
  - ただ、ビジネスプロセスモデリングやソフトウェアモデリングになると、ドメインモデルや集約の知識が必要になると感じる。
　　
- **ファシリテーターの役割が重要！**

## 6. 最後に
今回のワークショップを通じて、イベントストーミングを体感することができ、非常に有意義な時間を過ごすことができました。

まだまだ実践レベルには達していないので、日々の開発の中でイベントストーミングを意識的に取り入れていこうと思います。

また、モデリング力をさらに高めたいと強く感じたので、**UMTP認定試験の受験も視野**に入れて、モデリングの勉強を続けていきたいと思います。