Event-Storming 工作坊:探索業務全景
最近在公司內部組織了幾場 Event Storming Workshop,這篇文章算是作為組織者交付的一份作業,希望更多同學可以瞭解並且組織這樣的活動。
背景
假設我們是一家 B2C 的電商平臺,姑且就叫做 “京西” 商城,創業一年多,創業初期野蠻生長,系統也是 “大泥球(單體應用)” 。公司發展很好,又融資 2000萬美金,公司業務需要迅速擴張,而現有系統難以支撐公司業務的快速發展,需要進行微服務的拆分,同時開發團隊的規模也要從過去的 20 人增加到 100 人。
新加入的同學需要快速瞭解現有業務,而產品經理也無法對所有業務進行完整描述,過去的開發人員只瞭解區域性業務。業務需求無論是 “使用者故事” 還是厚厚一沓需求文件,都難以讓新老同學有一個 快速的 、 統一的 完整認知。
ofollow,noindex">Event Storming
針對以上的種種困難,我們可以採用 Event Storming 輕量級建模工具,來幫助我們較短的時間內快速理解業務的全景,達到統一的認知。
Event Storming 是按照 DDD(Domain Driven Design)的思想所派生出來的建模工具,當我們使用 Event Storming 去探索業務全景的同時,也產出了對業務系統的建模設計,這是與 User Journey 、使用者故事地圖(User Story Mapping)工具的最大區別。
原則:通用語言
在過程中我們需要遵守的重要原則是 通用語言 (並不是其他原則不重要,而是我沒記住,哈哈) 。通用語言在 DDD 中也是重要原則之一。有兩層含義:
- 在我們描述業務系統時一定要使用業務場景中的方言,例如,在一件商品被賣空之後,我們電商業務會說 “售罄” ,在餐飲業務中會說 “估清” 。再比如:在很多系統中都會看到如下詞彙“使用者”、“客戶”、“顧客”,這些詞彙意思過於相近且難以區分,而在電商業務中更有表現力的詞彙是 “買家” 、 “賣家” 。一方面強調所有人統一語言,另一方面減少大家的溝通成本。
- 剛剛說的是純粹在語言上的通用,而另一層含義是在系統中。你有沒有發程式員只是計算機的翻譯,我們將業務邏輯翻譯成計算機能夠理解的語言,而產品經理卻是將業務語言翻譯成程式設計師能夠理解的邏輯。中間有大量的語言轉換,導致我們的系統與真實的業務相差甚遠,這其實是不應該出現的一種結果。正確的結果是我們的系統結構與真實世界是一一對應。這一點在以後的 DDD 的文章中再詳細闡述。
準備工作
尋找一個風和日麗的下午,一個大會議室,還要有一個巨大的白板、各種顏色的便籤貼。

帶有時間軸的白板
邀請上我們所有需要了解業務的同學:
- 領域專家(業務專家)
- 產品經理
- 架構師
- DEV
- QA
- ...
我們可以邀請所有的相關人員,必不可少的是我們的 領域專家 ,在沒有領域專家的指導下我們很容易會按照自己的理解而走偏。
如何開始?
首先,由領域專家將業務背景進行一個大致的介紹,不需要很全面,讓大家有一個基本的認識,然後按照如下步驟操作。
根據經驗,如果參與的同學對業務完全陌生會導致兩個極端:1. 所有人只是在觀看領域專家在貼,無法參與其中。2. 人們在根據自己的理解胡亂貼便籤,而領域專家需要不斷糾正。雖然出現不同的想法是我們所希望看到的,但大量的糾正會導致時間上的浪費。
領域專家帶領大家找到系統中認為最重要的 領域事件 ,貼在我們的帶有時間軸的白板上。
貼領域事件——什麼是領域事件(Domain Event)?
在系統中真實發生,需要被記錄的事件 (大資料的同學,請不要說話!) ,且會對系統做出 反應 。需要被記錄的事件也就意味著需要被追溯。舉個例子:電商系統中產生了一筆交易,同時對買家的積分進行了增加。增加積分的事件則需要被記錄,而不是單純的對分數進行修改。當用戶希望知道我的積分都去哪了,我們就可以將這些事件進行追溯。
大資料的同學會認為所有的事件都應該被記錄,為什麼不讓說話???並不是對大資料同學的歧視,大資料並不屬於業務系統,而是橫切所有系統。

領域事件
用橙色的便利貼表示領域事件,使用 名詞 + 動詞過去式,例如:訂單已建立。通常以XX 已 XXX。
在帶有時間軸的白板上貼上我們剛剛寫好的事件,你認為在事件軸上的任意位置。以這張卡為參照,相繼貼上在這張卡之前和之後的事件。
此時可以讓每人輪流讀出自己寫好的卡片,並貼到白板上。如果參與的人數過多可以根據事件前後和參與人數進行分組。在貼卡的過程中,領域專家和組織者可以回答大家的業務問題,以及糾正卡片的錯誤。
最後,領域專家要帶領大家將貼好的卡片進行梳理,剔除重複的卡片,刪除在業務系統中不存在的事件等等。在梳理的過程中會發現很多意想不到的卡片,我們後面再講。
貼Policy——什麼是Policy?
Policy 不太好翻譯,翻譯成“政策”有一點點奇怪, 是在較新的資料中才有,我們可以理解為規則。
在一些業務設計過程中會有很多的規則,這些規則通常不能被建模工具有效的方式表示,都變成了“潛規則”。例如:
使用者輸錯3次密碼之後需要鎖定賬戶。
輸錯3次密碼就是我們的 Policy, 鎖定賬戶 則是 Policy 觸發的新領域事件。

Policy
用紫色的便利貼表示 Policy 。
貼命令——什麼是命令(Command)?
事件貼完了,接下來我們可開始貼 命令 。我們需要探索使用者如何與我們的系統進行互動,命令代表著使用者與系統的互動,而事件則是發生互動之後所產生的。

命令
用藍色的卡片表示命令。與 CQRS(Command Query Responsibility Segregation)的Command 含義相同。
PS: 由於 命令 * 與 領域事件 大部分是可以一一對應,為節省時間,可以在workshop 中適當省略。*
貼讀模型——什麼是讀模型(Read Model)
在寫 領域事件 的過程中出現了這樣一張卡:

奇怪的領域事件
首先,我們需要先確認這張卡是否真的有這樣的業務。買家是否有一個功能是可以看到自己所瀏覽過的商品列表?通常瀏覽列表不會被記錄,記錄的往往是商品詳情,可能會有一個【最近瀏覽的商品】的功能與之對應,那麼我們可以這樣寫:

商品瀏覽已收錄
有同學可能會說,我就是想標記出買家所看到的東西,有什麼卡片可以幫助我們嗎?這就是—— 讀模型 。
讀模型與 Policy 都是較新的資料才出現的。是表示使用者所看到的東西,之後使用者會發出命令。

讀模型
用淺綠色來表示讀模型。與 CQRS 的 Query 含義相同。
貼角色(role)
角色是系統中必不可少的,我們可以輕易的識別出這一系列卡片由哪個角色觸發。

角色
用黃色表示角色。
貼到這裡可以看出牆上的卡片已經可以連成一句話:【買家】在【檢視購物車列表】後【提交訂單】完成【訂單已建立】,與我們寫的使用者故事越來越接近。
貼外部系統(External System)
在開發系統時多多少少都會與外部系統做整合,例如:支付系統、簡訊系統等等。我們通過淺粉色的卡片將外部系統表示出來。

外部系統
劃分子域(Sub Domain)
啥是業務子域?我們得先了解一下什麼是 領域 (在文中下方有對 領域 的解釋)。
領域:在文中提到了大量的“領域” ,在沒有了解過 DDD 的同學肯定暈菜了。我們先來看看書上是怎麼說的:
領域(Domain)即是一個組織所做的事情以及其中所包含的一切。... 每個組織都有它自己的業務範圍和做事方式。這個業務範圍以及在其中所進行的活動便是領域。
——《實現領域驅動設計》
我們可以單純的理解為 “整個業務” ,為什麼不直接說 “業務” 呢?業務的含義過於廣泛,而且一點都不神祕,不夠酷!
為分解領域的複雜度,將領域劃分為若干個子領。
就好比一個龐大的複雜裝置是由千萬個部件組成,而每一個部件又是由千萬個零件組成。其目的是為了降低單個部件的複雜度,只需要將複雜構造和邏輯封裝到部件內部,對外暴露出簡單的介面即可。
子域理解起來相對容易,但想要 合理 的劃分起來卻非常困難,需要對這個子域中發生的所有事件劃到一個 Scope 中,在探索的階段我們可以暫時將事件的名詞提煉出來,作為我們子域。

劃分子域
PS:子域的劃分正確並不容易,在專案初期並不建議過細粒度的劃分,需要等業務邊界足夠穩定我們再將其劃分。
到這一步我們已經完成了對業務全景圖的探索,下面我們來玩一些更有趣的卡片。
貼警告資訊(Hot spot)
現在我要給每個人手裡發一把“大錘”,找出系統中你認為可能出現問題的“釘子”,用深粉標記出來。我們站在挑刺的角度可以發現系統中可能出現的很多問題,程式設計師尤其擅長這一點。當然,這裡的“問題”不僅僅是開發時的問題,也可以是業務問題,或是流程問題,外部系統的問題。

警告資訊
投票評選瓶頸(Bottleneck)
既然選出了“熱點問題”,接下來我們來給這些問題進行投票,找出我們需要優先解決的問題。每人一票(可根據情況適當增加),使用畫有箭頭的藍色便利貼表示。

投票評選瓶頸
貼新的商機或者價值(Opportunity)
現在我要重新發給每一個一把新的“大錘”,找出我們系統中可能存在的商機或者價值。例如:我們是否可以提供 Plus 會員服務,是否在充值的基礎上提供金融服務等等…使用綠色的便利貼表示。

新的商機或者價值
其他有趣的元素
這些卡片並非一成不變,我們可以根據自己的需求給卡片加上圖示,賦予便籤特殊的含義。例如:定時任務、排程程式等等...

其他有趣的元素
總結
以上就是我們今天所產出的所有內容,這些卡片可以幫助產品經理輕易的編寫“使用者故事”,同時還可以幫助開發人員業務建模,如果採用響應式程式設計(Reactive Programming)作為程式設計模型就可以將產出直接翻譯成程式碼。
有參與過其他 Event Storming Workshop 的同學可能會發現與以往的不太一樣。的確,Workshop 只是一種手段,Event Storming 做為建模工具也並非一成不變,卡片的顏色、順序、多少可能不盡相同,只要為我們達到想要的目的就是好工具,不必要一定相同。
Workshop 的過程不僅僅是出貼便籤,還希望我們在貼便籤過程更多的溝通。幫助參與者達到快速統一的理解。也希望大家能夠在內部多組織這樣的活動,謝謝!