---
# System prepended metadata

title: 來場輕便可攜的 Event Storming 吧！

---

# 來場輕便可攜的 Event Storming 吧！

> 先有經驗，再學知識
 

當各個遊戲組別開始進行討論時，第一個會遇到的難題是 Event Storming 是什麼？以我自己的經驗來說，當初為了理解 Event Storming 是什麼，去買了本《[Introducing Event Storming](https://www.eventstorming.com/book/)》來看，看完後多少有一點理解，配合著網路上大量的範例也試著做自己的練習，這啟動的成本太高了！

你可以在學院的 [miro](https://miro.com/app/board/uXjVPLbiyto=/) 中找到圖例：

![](https://i.imgur.com/SSAmCXS.png)


最初在學習時，也看了各種影片與資料去弄懂圖例。後來，反覆參與讀書會，觀看示範才發現。其實，我們並不需要先學習那麼多。如同《[Introducing Event Storming](https://www.eventstorming.com/book/)》開始告訴我們的，作為「引導師 (Facilitator)」不要花太多時間介紹各種便利貼的意義，**直接示範應該要做些什麼，自己先動起來，讓參與者跟隨與模仿你的行為**。

- 核對期望與行為準則
- 事件風暴 (事件的膨脹與收斂)
- 事出必有因 (Command 與 Rule)

## 建立共同期望

![](https://i.imgur.com/u0JvGiD.png)


我們一群人來參加 Event Storming 型式的工作坊。要先對它能做到什麼，以及它的產出有個理解。首先，在 miro 上堆好的各示便利貼只是「副產物」，真的產出是與會者的**認知大致同步且滿意結果**。

先來關心會有哪些參與者，特別是針對商業流程建模 (process modeling) 的工作坊來說：

> 不會只有「開發者」參與。
> 

> 不會只有「開發者」參與。
> 

> 不會只有「開發者」參與。
> 

先放棄以開發者本位的思考方式很重要，要先說三次強調請開發人員切換為**人類友善模式**。這個工作坊的終點是利益關係 (stakeholder) 者與領域專家 (domain expert) 都覺得滿意，其他各種角色也都獲得一致的想法。因此，在這個工作坊中，不談技術細節，只會有描述商業行為的語句。

同步認知不只是個望願，最終的反應是每一位參與者，可以依著時間軸的推進講出完整的故事 (story telling)。並且，在這講述的過程中，不同的參與者用的**術語**會是一致的。這術語一致的情況，會同時呈現在下列地方：

- miro 畫布上，即 Event Storming 完成的 process
- PO、UX/UI designer 乃至 marketing 等非開發人員討論時用的術語
- 開發者 `OOA/D` 使用到的類別、方法、參數名稱

這就是統一語言 (ubiquitous language) 追求的結果，不會再是**非開發者**與**開發者**講著不同的方言，如同人月神化裡講述的巴比倫塔工程，越到後期歧異越大，最終讓開發速度因溝通的成本太高，而無法再進一步。

## 事件風暴

如同開頭說的「先有經驗，再學知識」。這裡的經驗不是問你有沒有精熟後自己操作或帶領它人進行 Workspace 的經驗，相反的，儘管你瞢瞢懂懂時親身參與過 Workspace，以第一人稱視角獲得的親身體驗。

### 階段一：讓事件風暴起來

作為主持工作坊的人，不需要解說太多「Domain Event」的細節，太多細節讓參與者困惑，而困惑的感受讓人無法好好品味後續的刺激。

一切會在引導師講述今日目標與貼上第一組破冰事件開始：「各位參與 UNO 團隊的朋友們好，今天事件風暴的目標，我們來 modeling 遊戲開始到一位玩家獲得一局勝利的流程」。有目標是重要的，這樣事件生長的方向才會比較明確有範圍，更何況有些遊戲的流程太複雜，不先聚焦一下會讓事件發散地過多，後續要花費較久的時間收斂。

![](https://i.imgur.com/qdrFbAn.png)

以上面簡單的例子來說，這二張也許都是引導師示範的。一開始也不用太在意 timeline，事件的順便不合理也沒有關係，總之先把各種事件生出來。直到看似足滿「遊戲開始到一位玩家獲得一局勝利的流程」。

在這一段引導師要示範 ***Thinking Out Loud***，把正在想的東西以讓其他人聽得到的音量也說出來，同時鼓勵大家這麼做。因為「同步認知」，要先知道他人有沒有想法與自己不同，或是被他人的想法同步。

稍為提醒一下，在每一個活動的階段都設個 **timebox**，例如 10 分鐘或 15 分鐘，也可以更短不夠再加時間。

### 階段二：文法與時序

在上一輪讓參與者填上各種事件後，第二階段可以開始來加一點點的「Event Storming 規則」，也只有一點點：

- 事件的內容用**過去式**描述
- 事件**時序**是由左至右排列的

由於一套流程要成立，得透過實際觀察到的事實來決定它合不合理。這些被領域專家觀察到的事實，就可以被寫成 Domain Event。在這階段，參與者只需要知道我們在描述「已發生的事實」，所以有著使用過去式來描述它的慣例。

下圖是借用自先前參與引導的 uno 組別的範例：

![](https://i.imgur.com/fR2z0C9.png)

在第一階段時，引導師不用特別修「過去式」，也不需要特別去提醒參與者「事件需符合時序排序」，因為這些內容都可以是同步認知的一環。要大家一起來修護比較值得，若只是單純某個人內心中的小劇場，那就太浪費了這些素材了。

引導師可能會講這些內容：

- 在這堆事件之中，有哪個事件它應該是第一個發生的！？
    - 遊戲已建立 → 有需要修文法或文字嗎？
- 接著續的事件，是誰比較合理？
    - 牌局已開始 → 有需要修文法或文字嗎？
- 回到遊戲規則，有沒有我們遺漏的事件，可以排入目前的二個事件之前或之後呢？

過程都會是這些活動的循環：

- 選擇未排序事件
- 事件決定先後關係
- 修正事件內容的文法
- 挑選適合的術語
- 發掘遺漏的事件

經過一番努力後，會發現「有序」的事件在變多。反覆上述的流程，把「無序」納入有序的歷程，就是在這階段最重要的事。

![](https://i.imgur.com/q8gUdrk.png)


要注意，如果時間太久讓參與者經神不濟就不好了。因為，完成排序是最重的目標，但不是工作坊主要的目標「同步認知」。精神力低落時，腦中是無法再接收新的知識的，當領域知識太旁大時，可以分不同批次慢慢把它執行完。

### 階段三：說故事

![](https://i.imgur.com/C92FjBm.jpg)


「說故事」story telling 並不一定得在**階段二**完成才可以執行，只要我們在時序上有一些進展的時候都很適合。說故事就是利用已排好的事件串連起來的描述：

> 當遊戲已建立後，就能開始新的牌局。選出第一位玩家，他會負責洗牌與發牌，每位玩家會得到七張牌，接著，由牌疊抽出第一張牌放在檯面上，正面朝上讓玩家都看到。玩家已由牌堆翻開第一張牌，並打出它。
> 

需要請參與者仔細聆聽說故事的**細節**，因為為了串連起故事，說故事的人會去自動補足「事件」中不連貫的部分，也會突顯事件中缺乏的細節與用語不一致的部分。在這個階段，是做製造「討論」與「同步認知」的好時機。

### 階段四：命令與規則

我們知道 Domain Event 並不會無緣無故自己發生，它得有一個發生的原因。肯定來自某種機制做了些什麼，我們先討論直覺得情境：

> Command 產生 Domain Event
> 

![](https://i.imgur.com/82djCgX.png)


借用《出包魔法師》的 Event Storming 圖例，在這個遊戲中我們找出一個遊戲過程中必需發生的事件「已完成遊戲設置」，我們得替這個事件找個觸發的 Command，於是拉了一張藍色便利貼寫著「設置遊戲」就搞定了。

針對 Event Storming 畫布上的每一個 Domain Event 我們都先 **「無腦地」** 幫他加上對應的 Command。就只是把「過去式」的 Domain Event 換成另一個「動詞」開始的句子罷了。

不過，Command 幫助我們思考的，其實是它本身帶有「責任」，責任完成才能產生 Domain Event。所以，這時，經典款的淺黃色便利貼就要上場囉！我們得在這貼利便中描述 **Rule -** 規則。當規則內的事項完成了，才可以有自信地說 Domain Event 所代表的事實被確立了。

![](https://i.imgur.com/TtZKxRr.png)

所以，我們看著規則回推「已完成遊戲設置」時遊戲會處於什麼狀態呢？

- 遊戲圖板已經被重設囉！→ 不會有前一局殘留的內容。
- 魔法石洗勻 → 所有的魔法石都在我們的「遊戲」管理之中，並且重新洗牌成打亂的順序。
- 替玩家分配魔法石 → 遊戲參與的 N 個玩家，每人得到 5 個魔法石，但自己不知道自己的魔法石，只能看得到別人的魔法石。
- 每位玩家獲得 6 枚生命指示物 → 俗稱血量的東西，不管經過幾局，重新開始就是 6 點起跳。
- 由剩下的魔法石堆，取出 4 顆作為秘密魔法石。→ 剛剛抽剩下未分配的魔法石中，再抽出 4 個當作秘密魔法石。
- 選定該局初始玩家。

所以，我們可以有信心地說「已完成遊戲設置」就是上面規則由 Command 執行完成。儘管不一定每一個 Command 都有複雜的規則，但這個階段讓我們省思什麼情況，代表了 Domain Event 確實發生了。

> Q：如果有任何條件無法被滿足，該如何是好呢？
> 

如果有任何條件被滿足，那它跟我們目前探討的 Domain Event 應該是屬於互斥的關係，你再立一個新的 Domain Event 看它是否值得有獨立的 Command 能來作為觸發點。或者，你在規則中多描述特定事件，只有在某些情況才會發生。

請參考「詠唱失敗」的例子：

![](https://i.imgur.com/T82isFY.png)


當玩家詠唱失敗，一定會扣除若干生命點數，但是玩家不一定會死亡。這就是 Domain Event 不一定會觸發的原因。同時，這個例子你也可以看到一個 Command 可以產生一個以上的 Domain Event，這都是合理的情境。

在補足 Command 與 Rule 後，推薦再次進行「說故事」環節，因為這次有了明確的「動詞」與「該滿足的條件」描述起來會更加流暢。

### 其它：Policy

Policy 並不是必要的，它的出現理解它用來表現二種目的：

- 結構上的功能，用來連結二組 Domain Event
- 強調是一個重要的 Business Logic (這時，它可能是一個專業術語；或是描述著豐富情境的句子，來描寫為何二組 Domain Event 該連在一起)

結構上它得符合這個型式：

```
Whenever [events] then do [command]
```

用上面的例子來套，就會是：

```
Whenever 玩家已死亡 then do 結束局
```

白話地說：

- 無論什麼時候，只要玩家死掉了，就結束該局。
- 無論什麼時候，只要玩家死掉了，這局就結束了。 (用事件來描述也沒什問題)

Policy 通常是用來「強調」與「同步認知」的意圖，就算你的 Event Storming 畫布完全都沒有 Policy 也不會產生任何問題。因為 Policy 多半的時候，可以是 Rule 的一部分，特別拿出來講是為了強調這看法是對的，無法撼動的。

在書上教 Policy 是一個**測謊器**，當你試著把 always 或 immediately 放到句子中，在場的參與者有任何一個人反對，那目前這一版的 Policy 地位就受到撼動，因為它不符合 always 與 immediately 存在的情況。這時，你可以做的是去釐清陳述中的哪一部分導致 Policy 失效，透過建立互斥的 Domain Event 來讓 Policy 合理。

### 其它：Rule 的分類

到目前為止，我們沒有細談 Rule，因為在最初的一二三階段，並不需要理解那麼多。它可以分為三類：

- 固定規則 invariants
- 前置條件 pre-condition
- 後置條件 post-condition

![](https://i.imgur.com/VDSuvST.png)

所謂「固定規則」，使用的情況這個 Rule 無論在哪一個 Command 發生都要保持，是屬於整個 Domain 都要遵守的事情，像是一開始的遊戲人數限制，就是固定規則的一種。

接著 post-condition，這就是我們剛剛寫在 Rule 裡的內容，如果沒有特別寫你當作 invariants 或 post-condition 都可以，滿足了 post-condition 才能產生 Domain Event。另一種 pre-condition 就還沒提過了，這是要「符合條件」才能執行 Command，也就是「Actor 有執行這 Command 的資格嗎？」

## 動手做 Event Storming

對於這份寫給自己看的「引導」筆記，也許稍長了點。若你打算使用它來自我引導，建議不要吸收太多知識，先快速地拿很多套遊戲，反覆練習階段一二三就好。其它的只是加分項目，但只要階段一二練得熟，階段三自然順利。後續的接 Command 就只是更細節地檢查規則罷了。儘可能多動手做，少停下來迷惘。