そのプロダクトにポリシーはありますか？（イベントストーミング実施編）


[GLOBIS Advent Calendar 2021](https://qiita.com/advent-calendar/2021/globis) 13日目の記事です。

[昨日のエントリ](https://qiita.com/tatsushitoji/items/08be995ba1acafda970d)では @tatsushitoji が、イベントストーミングという手法をチームに提案・導入した背景やその効果について書いてくれました。

続編として、今回は「具体的にどうやってイベントストーミングを実践したのか」についてご紹介したいと思います。

# ようこそ、イベントストーミング実践編へ！

僕たちがイベントストーミングを始めるにあたって、もっとも困ったことは実際のケース紹介が少ないことでした。
今回は具体的なテーマに則して、僕たちなりの改良を交えた進め方をご紹介したいと思います。

テーマとしては、Qiitaのアドベントカレンダー投稿機能を考えてみます[^1]。
[^1]: 個人で勝手に妄想した内容なので、実態と違うかもしれませんが、あくまでサンプルとして参考にしてみてください。

![スクリーンショット 2021-12-23 18.45.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/844b5adb-d9e3-9964-5312-68eb313e1e2f.png)
（アドベントブログの登録画面があり、リンクを登録しておけば当日に自動公開される・・という機能を想定しています）

イベントストーミングプログラムの具体的な立て方については、実践編の後に解説していきたいと思いますが、[こちら](https://miro.com/miroverse/event-storming/)をベースにしています。
Step4を省いたり、Step2、Step3を細かく分割したりしていますが、僕たちの目的にあわせて試行錯誤した結果を反映してチューニングしたものになります。


## STEP1 – カオス探索
まず最初のラウンドでは思いつく限りの「ドメインイベント」を書き出します。
イベントは、必ず１つについて一枚のオレンジふせんを使い、**過去形の動詞**で表現します。
出したふせんが人と違っていても、同じ内容が重複していても構いません（質より量が大切）

ここで大事なことはひとつ。**議論に深入りしすぎないこと**です。

わからないことや解決できない疑問は、プロセスの後半に行くに連れて自然に合意が導かれていきます。
無理に解決しようとせず、大切な気づきとして全てピンクふせんに残すようにしてください。

![step1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/b0a4da0c-b648-d99a-4dc7-5bca6a85703d.jpeg)

特にここで「イベントとは・・？」と言う疑問が出てくるかと思います。
「ドメインイベント」とはビジネスプロセスで起こった重要な出来事のこと・・となっていますが、全員がいきなり腹落ちするのはむづかしいかもしれません。
ゆくゆく精査できるので、ひとまずは雰囲気で書いてもらうくらいでいいでしょう。

もしユーザーのタイプごとに操作が異なる（例：管理者と一般ユーザー）ような場合は、ユーザーごとにイベントのレーンを分けましょう。
ユーザーは黄色ふせんで表現します。

## STEP2 イベントの蒸留

ここではSTEP1でつくったボードを見ながら、全員でドメインイベントのポストイットを吟味していきます。
発散したイベントを議論をしながら収束するプロセスです。

### （A） タイムラインの精査
まず参加者たちには、それぞれのポストイットの意味を説明してもらい似たものはグルーピングします。
ポストイットは語句が完全に重複していないかぎりまだ削除する必要はありません。（語彙の揺れも重要な発見です）

また、イベントが正しく時系列に並んでいるかどうかについてもチェックしましょう。

### （B） 疑問の解消
Aと並行してピンク付箋の疑問も読み上げていき、それぞれについてグループで結論を出していきます。

ここでは往々にして、スコープについての疑問・議論が生まれます。
たとえば、「アドベントが近づいて来た時にお知らせを飛ばすかどうか（お知らせ機能をフローとして含めるかどうか）」という感じです。
アドバイスとしては、**「あったら嬉しい」程度の機能、「なくてもなんとかなる機能」は限界までミニマムに倒す**のがいいでしょう。

最初から複雑なイベントフローを作ろうとするよりも、スコープの絞り込んだイベントフローにあとから機能追加していく方がはるかに簡単です。
忘れないように、スコープについての決定は赤ふせんに追記しておきます。

### (C) イベントの削ぎ落とし
抽出したイベントのうちで、上記のスコープ議論で不要になったものを取り払いましょう。
また、人間やシステムの動きに関係ないものもすべて取り払ってシンプルにしましょう。
おもに対象となるものは、「ユーザーが・・を決めた」という外部から見えない動作だったり、「理解した」という脳内の状態を表すものです。

### （D） ユビキタス言語の抽出
用語の使い方を検証します。
いろいろな言葉が同じものを指している場合は１つのポストイットに統一します。
逆に、似た用語が異なる対象を指すために使われていた場合は、違いが明確になるように言葉を明確化しましょう。
![スクリーンショット 2021-12-23 20.56.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/cfc9aabf-32ca-ca91-8485-c5f88a156fed.png)

たとえば上の例で言うなら、「限定共有公開」、「一般公開」のような言葉について揺れがないようにしておきたいところです。

## STEP3 起因分析
### (A) コマンド抽出
各イベントの起点となるコマンドを考えて、青ふせんを足していきましょう。（場合によっては、外部システム起因のイベントもあります。その場合はピンクふせんを足しましょう）
コマンドは名詞、または現在形の動詞にしてください。

![スクリーンショット 2021-12-23 20.57.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/fe211145-462c-1046-8edb-aa0afb02219d.png)

### (B) トリガー分析
コマンドを叩くのは、ユーザーなのか自動動作なのかを確認します。
ユーザーの場合は黄色ふせん、自動動作の場合は紫ふせんを足しましょう。

### (C) ポリシー（遷移条件）の完成
ここではポリシーと呼ばれる紫ふせんに注目します。

ポリシーには、「一定の時間になると勝手にコマンドを起動する」タイプのものがあります。
そのポリシーには「_<<日時>>_になるときはいつでも」というように、起動条件を書き込みましょう。
今回の場合、「アドベントの期間中、7:00AMになるときはいつでも」という条件を加えています。

そうでないポリシーには、起点となる別のイベントがあるはずです。
ポリシーには、その起点となるドメインイベントを結びつけましょう（イベントがなければあらたに加えましょう）。
ポリシーには、「_<<イベント>>_が起こる時はいつでも」「_<<イベント>>_が起こる時、もしXXXXXならば」というフォーマットで遷移条件を書き込みます。

複雑な複合条件がある場合、複数のポリシーをネストすることもOKとします。
![スクリーンショット 2021-12-23 20.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/e1f26254-feb5-2ab3-789f-d8e6a3ca417c.png)

キャプチャは途中までポリシーを入れていった段階です。

### (D) ビューの追加
一部のイベントは、UI・ビューを通じてユーザーに結果を通知します。ビューに当たるものを緑のふせんで明示しましょう。
また、このビューが影響を与える対象ユーザーを黄色ふせんで明示しましょう。

### (E) ライフサイクルの完成
ポストイット間の遷移を矢印で図示して、正しいライフサイクル[^2]になるようにフローを完成させます。
行き先のない矢印や、トリガーのないイベントなどがないようにし、繊維の順序が正しいかどうかを確認してください。

![スクリーンショット 2021-12-23 20.58.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/fca96fb3-d2a1-8595-72d5-227e5eafd753.png)

[^2]: 遷移ルールはこんな感じになっています。
      ![スクリーンショット 2021-12-23 20.49.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/3e4949bf-4c06-adbe-f602-c73f9acd2dd4.png)
    （[Introducing EventStorming](https://www.eventstorming.com/book/) "picture that explains everything"より起こした図。外部システム駆動の点線のみ追記しています）


僕たちが実施している簡略フローとしてはここまでになります。（必要に応じてこの後集約を見つける作業をしてください）

最後に重要なこととしては、ステップは途中で戻っても構わないことを忘れないようにしてください。
あまりステップごとに頑張りすぎず、議論の進展を見ながら行ったり戻ったりするくらいでちょうどいいでしょう。

# イベンストストーミングここに気を付けろ！３つの勘所

以下は、イベントストーミングを実際に導入してみたいという方へ向けた企画面でのTIPSです。

実際に自分たちが何度もやってみた結果を振り返ってみて、特に事前に気をつけておくべきところだったと思ったところを紹介したいと思います。

## 1. 目的を絞る

そもそもですが、イベントストーミングは柔軟なフレームワークなので「この通りに進めれば万事OK」という脳死マニュアルはありません[^3]。

[自分たちの直面している課題](https://qiita.com/tatsushitoji/items/08be995ba1acafda970d#%E8%AA%B2%E9%A1%8C)を考えた結果、僕たちは、**dev/bizのチーム間で仕様の共通理解を持つ**、ということを一番の目的にしました。

具体的には、「顧客からニーズが強いが、仕様の振れ幅が大きく、全部をカバーすると途方もない工数になる特定の新機能」のモデリングをテーマにしました。
「顧客のペインの大きさ × リリースまでの時間にかかわる仕様の複雑さ」のトレードオフを考え、ミニマムかつバランスの良い解決策の方向性についてのコンセンサスが取れれば成功、と考えました。

企画段階でこの目的を絞り込んでおいたことが、実施に向けたステークスホルダーへの説得や、実際の進行にあたってとても役に立ちました。


[^3]: たとえば、[Introducing EventStorming](https://www.eventstorming.com/book/)には、
      > there is no 'best way'.
      > In practice, there are several ways to run an EventStorming, with different purposes and rules...
     「目的に応じていろんな形があり得るよ」ということが説明されています。


## 2. プログラムをアレンジする

こちらで紹介されているテンプレートを参考にさせていただきました。

https://miro.com/miroverse/event-storming/

このテンプレートを日本語化したものをベースに、アレンジを加えています。
（日本語にはかなり我々の解釈や超訳が含まれます）

![スクリーンショット 2021-12-13 20.01.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/22f1584c-e43b-9dce-2577-6d7bd771d5ca.png)

僕たちはチームの拘束時間としてトータル４時間程度しか使えないという事情があり、この中で目的にそぐわないものはバッサリと捨てることにしました。

ここに関しては、上で紹介した通り、２点大きな決めをしています。

#### Step4のソフトウェアモデリングには踏み込まない
まだリリース一年目の小さなプロダクトであり、責務の分割線に関しても比較的に明らかで悩む部分が少ない。またアーキテクチャとしてもほぼ同期的に動くシンプルなモノリスであり、集約やその責務の洗い出しについては、必要に応じてエンジニアで巻き取れば十分と考えました。

#### アプリケーション全体のモデリングは行わず、スコープを新機能に絞る
議論の対象となる新機能と、それに関連するシステムの一部のみを対象にしました。結果的に、より短い時間で全体プロセスを一周まわしてもらうことができ、参加者にメリットや面白さを体感してもらいやすかったというメリットもありました。

## 3. 実施する

#### コンセンサスを取る
ステークスホルダーに実施のコンセンサスを取っておきます。忙しい開発チームにおいてここは難関ですね。
イベントストーミングは「やってみて初めて価値がわかる」という部分もあるので、まずは目的やスコープを小さく絞り込み、短めの時間でやってみるのがおすすめです。
インフォーマルに有志を巻き込んでおくといいかもしれません。（巻き込まれた人）

#### メンバーを決める

最低限としては、ドメインエキスパートと開発者とされてます。
僕たちは以下のような人たちに出席を依頼しました。

* **ドメインエキスパート**
ビジネスドメインを詳しく理解している人（複数可）。
顧客のペインだったり、望まれている機能のユースケースを提供することで、意味のある機能にたどり着くのを助けます。

* **プロダクトオーナー**
参加者として意見を出してもらうのはもちろん、スコープを絞り込んだり、複数のアイデアから検証したい方向性を仮決定していく際の判断を担当してもらいます。

* **デザイナー**
エンジニアと一緒に、なぜその機能が必要なのか・ユーザーはどう使うのか、という質問を投げかけたり、解決策を提案します。
ユーザー体験面から発想するデザイナーのインプットや提案は貴重ですね。

* **エンジニア**
モデリングにあたっての不明点を質問する係です。ドメインエキスパートに質問を浴びせたり、POに曖昧になっているポイントの仮決定をせまります。
仕様の矛盾だったり、フローでカバーされていない落とし穴を見つけるのはエンジニアの得意分野ですね。

* **ファシリテーター**
  全体の進行を促します。可能ならスクラムマスターにお願いするのもいいと思います。
 * 議論が生産的・創造的になるような雰囲気づくり
 * アイデアの発散とスコープの収束のコントロール
 * 機能の矛盾を投げかけたり、ユビキタス言語の不一致を指摘したりするツッコミ役


#### ツールや会場を設定する
今回はオンライン実施なので、ツールとしてmiroを利用しました。
リアルで実施する場合は、イーゼルパッド・模造紙や、色付きポストイット・ペンなどが必要になりますね。また会場の設営も重要です。

#### 事前説明の時間を取っておく
当日でも大丈夫ですが、時短のためには重要です。以下のポイントに気をつけました。

* 前提知識を共有する（イベストの意義、目的や手法の説明）
* コンテキストの設定（会議ではなく、自由なアイデア創出と検証の場であるということを伝える）
* 技術的な問題がないことを確認しておく（参加者がmiroにアクセスができることを確認する、など）

#### シミュレーションをする

この辺り地味に大事です。
企画者だけで一度回してみることで、議論が発散しそうなポイントを把握したり、わかりにくいポイントに説明を入れたりすることができます。
また、参加者が求められているものを理解できるように、あらかじめドメインイベントや質問のふせんを仕込んでおくという作業もしています。

#### 当日

あとは心静かに行うだけですね。
留意点として、以下のようなことに気をつけました。

1. ワークショップルールの徹底
 ワークショップ慣れしていない人がいる場合は、「人のアイデアを否定せず、乗っかっていこう」「疑問に思ったことは全てメモで共有しよう・・」などなど
 基本ルールを説明しておくのがいいかもしれません。

2. ステップを戻ることを恐れない
必要に応じて前後行ったり来たりしましょう。
最後のほうにいってもなおイベントやユビキタス言語が漏れてることに気づくことは多々ありますが、その都度ステップを戻して議論しましょう。

3. 少人数グループにすることで発言機会をつくる
 オンラインの場合どうしても一人一人の発言機会が制約されがちなので、ステップ３以降だけ３・４人程度のチームに分割するのもいいと思います。
（ただしステップ２「ユビキタス言語」までは１チームでやったほうがよい）

5. アンケートをとる
フィードバックを取りましょう。好評だったなら単純にモチベーションも上がるし、次回以降の開催においてもいい材料にもなりますね。

![チャート.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151343/61d10c5f-adec-e7ea-bbf8-2e4a241af8ba.jpeg)


# 最後に個人的な感想

@tatsushitoji にこの提案をもらった当初は、「自分たちでクラス図をちゃちゃっと書いた方が早いんじゃないの？」なんて思っていました。

ところが、やってみると目からウロコ感がすごい。

モデルがサクッと可視化できるし、ついでにユビキタス言語も得られる！
その中でもっとも重要だと感じたものは、プロダクトの仕様に内包される**ポリシー**の発見です（伏線回収）

たとえば先ほどのサンプルでは、右上にあるアドベント公開時の処理に関して、たくさんの紫ふせん＝ポリシーが見えます。
ここは条件分岐ロジックやデータの状態が複雑であり、実装やテストの行数が膨らむ箇所じゃないかな、ということが見て取れます（もちろん、複雑な仕様が悪というわけではない）
優先順位と実装コストを踏まえた現実的な仕様を策定する上で、こういた形でドメインロジックの複雑さを可視化し、biz/devで共有して解決していける仕組みは他のどの手法にもないいいやり方だと感じています。

[^4]: 「イベント ⇨ ポリシー ⇨ コマンド」のチェーンを、そのままマニュアルオペレーション（ビュー ⇨ ユーザー ⇨ コマンド）を差し替えることになります。


与太話ですが、[昨年エントリ](https://qiita.com/fursich/items/3292ce24faa8640bf285#%E3%81%8A%E5%89%8D%E3%81%AF%E3%81%AA%E3%82%93%E3%81%AA%E3%81%AE)でも触れたとおり、以前は広告代理店に所属していました。ブレインストーミングという手法を世界で最初に開発した[Alex Osborn氏](https://en.wikipedia.org/wiki/Alex_Faickney_Osborn)は、その会社の設立者の一人だったりもします。（だからといって自分自身のブレスト能力にはあまり関係ない）
ブレインストーミングにルーツを持つイベントストーミングは僕にとってもとてもなじみやすい手法で、「利害が複雑に対立する関係者があつまってコラボレーティブに課題を解決していく手法」という意味において、エッセンスはとても近いものだなと感じています。