java架構模式與設計模式(三)--事件風暴

本文來自

什麼是事件風暴

很多人在學習DDD的過程中,都會有一個疑問:DDD的概念看着挺多,聽起來也很有用。但具體怎麼落地實施到項目中?

事件風暴(Event Storming)於2013年首次被提出,2015年被ThoughtWorks技術雷達添加到“實驗”階段,2018年被ThoughtWorks技術雷達添加到“採納”階段。

事件風暴是一種快速探索複雜業務領域和對領域建模的實踐。

事件風暴從領域中關注的業務事件出發,在此過程中團隊經過充分討論,統一語言,最後找到領域模型。

那到底什麼是領域中關注的業務事件呢?

以寵物爲例,如果做爲寵物主人,你的問題域是如何養好一隻貓,那麼是不是已經打了疫苗,給寵物飼餵食物等將成爲你關注的事情,領域事件會有:疫苗已注射,貓糧已飼餵等。

如果你是寵物醫生,問題域是如何治好寵物的病,關注的事情是寵物的身體構成,準確的診斷寵物病情,對症下藥,領域事件會有:病情已確診,藥方已開治。雖說二者關注的都是寵物,在不同的問題域下領域事件是不同的。

如果在通用語言中存在“當a發生時,我們就需要做到b。”這樣的描述,則表明a可以定義成一個領域事件。領域事件的命名一般也就是“產生事件的對象名稱+完成的動作的過去式”的形式,比如:訂單已發貨(OrderDispatchedEvent)、訂單已收貨和訂單已確認(OrderConfirmedEvent)等事件。

領域事件可以是業務流程的一個步驟,例如訂單提交,客戶付費100元,訂單完工等。領域事件也可以是定時發生的事情,例如每晚對賬完成。或者是一個事件發生後引發的後續動作,比如確認收貨7天后自動將錢打到賣家賬戶,比如客戶輸錯密碼三次後發生鎖定賬戶。

事件風暴流程


物料準備


在事件風暴開始之前,需要準備以下物料:

  • 便利貼:一大堆,最少要四五種不同的顏色;
  • 記號筆:人手一支,用於在便利貼上寫寫寫;
  • 白板:最好足夠長,用來貼便利貼;
  • 開放空間:用於小組成員之間的充分討論。

參與人員

 

  • 組織者:組織者應當熟悉事件風暴的整個流程,能夠組織大家順利完成事件風暴;
  • 領域專家:領域專家應該是精通業務的人,在事件風暴過程中,要負責澄清一些業務上的概念,思考業務上有沒有遺漏的事件;
  • 項目成員:負責開發這個項目的成員,所有角色都可參加,比如BA、QA、UX、DEV。因爲事件風暴可以快速讓整個團隊瞭解整個項目的業務流程。

尋找領域事件


工作坊由尋找領域事件開始。領域事件一般用橘色的便利貼表示,書寫領域實踐的規則是使用被動語態,並按照時間順序貼在白紙上。

最開始可能很多成員都不知道該怎麼寫,或者不知道該怎麼尋找領域事件。可以由組織者寫下領域中發生的第一個事件。其它參與者會迅速的開始模仿,這時我們可以讓大家快速的進入狀態。

在遇到有疑惑的事件時,不必長時間阻塞在那裏討論,把它作爲標記記下來即可,後續再進行重點優化。可以貼一個比較醒目的便籤紙(比如紫色)在事件旁邊。

隨着我們對業務認識的不斷加深,可以隨時回顧和總結之前添加的內容,對於有問題的描述進行更正,對於表述不清楚的內容可以進行重寫。

事件是有相對順序的。可以把一系列有相對順序關係的事件放在一行上,從左到右排好。這樣有助於梳理領域事件,查看是否有遺漏。

尋找命令和角色


在收集完領域事件後,我們可以在此基礎上進一步探索系統核心事件的運行機制。這裏我們在之前的領域事件的基礎上加入指令和角色的概念。

指令代表系統中用戶的意圖、動作和決定,一般用藍色的便利貼表示;角色表一類特定用戶,一般用黃色便利貼表示。它們之間的關係是“角色”發送“指令”產生了“領域事件”(指令也可由外部系統觸發,外部系統通常用粉色的便利貼表示)。

通常來說,一個命令將對應到我們後續應用程序開發的一個API。

在尋找命令和角色的過程中,你可能會遇到某些命令會在“特定的條件下”觸發。比如:“當用戶通過新的設備登入時,系統會發送提醒通知”。通常,我們將這種系統的行爲邏輯稱爲策略,通常記錄在紫丁香色的便利貼上,放在命令旁邊。

尋找領域模型和聚合


當我們做完了上一個環節,就可以開始尋找系統中的領域模型和聚合了。我們把跟一個概念相同的指令和事件集合到一起,並用黃色的較大的便利貼表示領域模型。

把跟這個領域模型相關的命令放到左邊,事件放到右邊。需要注意的是,這個時候會去掉“事件的相對順序”這個概念,因爲我們已經不需要了。

可能有些領域模型不能作爲一個獨立存在的對象。它應該被另一個領域模型持有和使用。那這時候,可以考慮把兩個模型合起來,形成一個聚合。在最上面的模型就是這個聚合的聚合根,其之下的模型都是它的實體或值對象。

劃分子域和限界上下文


找到領域模型以後,我們應當就可以比較輕鬆地劃分子域和限界上下文了。

在劃分限界上下文的時候也可以反過來檢驗領域模型和通用語言的正確性。如果發現一個模型有歧義,那它就應該是限界上下文邊界的地方,我們應該重新思考這個模型,必要時進行拆分。

關於子域和限界上下文的概念可以參考本系列上一篇文章。

常見的問題


我們發現在實施事件風暴的過程中會遇到一些問題。這裏列舉一些常見的問題及解決方案。如果你的團隊在實施事件風暴或者實施DDD的過程中遇到什麼問題,歡迎留言交流探討。

事件的粒度?


我們在討論這個問題之前,首先要思考事件是什麼。事件是領域專家關心的業務事件。所以它不能比領域專家關心的業務更細,因爲那將毫無意義。

舉個例子,如果我們關心的是一個人一天的作息,那我們可能關心的是用戶已起牀,用戶已吃早餐,用戶已上班。但我們不會關心到更細節,比如:用戶已睜眼,用戶已洗漱,用戶已出門,用戶已上地鐵……

同時,事件粒度也不能太粗,因爲太粗粒度的事件不利於尋找領域模型。比如我們在平臺上發一篇文章的業務。如果你只寫一個“文章已發佈”,那就可能會丟失掉一些比較重要的業務流程。

嘗試改成:文章已保存,文章已申請審覈,文章已通過審覈,文章已審覈失敗,文章已對外發表,文章已加入分類,文章已推薦……你會發現,中間多了一個審覈的過程,如果不找到這些命令,就很有可能遺漏掉“文章審覈單”之類的模型。

對某個事件有歧義


這是好事情,說明你們團隊需要討論了,有時還可以發掘出原本可能沒有注意到的業務細節。但在實施事件風暴的時候,不必剛開始就花太多的時間在上面,阻塞了後面的事件發掘。而是應該先前面說的那樣,用一個醒目的標記記下來,後面再回過頭來充分討論。

或許最開始有歧義的地方,在事件逐漸完善,領域模型定義出來後,就沒有歧義了。

一個命令產生多個連鎖事件


這個是正常的,一個命令可能會觸發一個事件或者多個事件。也有可能一個事件觸發了另一個事件,只需要把它們貼在一起即可。

領域模型周圍的事件過多


這個時候你們應該警惕了。一個領域模型不應該包含過多的領域事件,因爲這會讓這個模型變得很大,很複雜。你們需要考慮把這個領域模型拆分開了。

仔細思考一下,這個領域模型是不是可以拆成兩個?一些下面的實體是不是可以拿出來單獨作爲一個聚合根?它們中的一些事件表述是不是有歧義?可不可以拆開來劃分到兩個限界上下文中?

比如“用戶”在權限上下文中我們關注的是它的角色和權限,它是否登錄成功,它的密碼等等。

而在商品上下文中,我們關注的是它的姓名,電話,地址等等。

這種情況,是應該把它們拆開的。

感覺命令就是事件的動詞?


很多時候其實就是這樣的。比如角色是用戶,命令是發佈,產生了事件文章已發佈。但也不完全是這樣,因爲在這個過程中可以統一語言。比如:用戶,喝水,產生的事件可以是用戶已補充水分,而不是用戶已喝水。

也有可能會有一些定時任務或者策略,這都有利於我們熟悉業務。更何況,找到命令可以指導我們後續的API開發,所以尋找命令是有必要的。

成員完全不熟悉業務怎麼辦?


可以由領域專家先進行業務大概流程的講解。如果有UX已經設計好的圖就更好了。大家可以在這個環節發出自己的疑問,澄清一些關鍵信息。

領域專家也可以把主要的業務流程寫下來,打印到紙上或者反映到大屏幕上。比如:

產品運營人員可以添加新的商品,編輯產品庫存,併發布到京西商城,用戶可以進行購買;當商品銷售價格和庫存數量發生變化後,產品運營人員會進行修改,並重新發布到商城。

沒有領域專家怎麼辦?


團隊總得是有人瞭解業務的。比如BA(有些團隊可能是PM、TL等)。如果實在沒有,可以讓領域專家寫一份上面那種主要的業務流程,大家按照這個業務流程來做。

但還是最好有一個領域專家,因爲出現分歧的時候是很需要溝通達成一致的。如果沒有領域專家在,團隊有可能得到一些不準確的模型和語言。

除此之外,團隊成員也可以查閱相關的文獻資料去了解業務。比如金融系統、醫療系統等等都是有現成的行業案例可以研究的。

敬請期待:

《DDD第4篇 - 架構》
————————————————
版權聲明:本文爲CSDN博主「Yasinxxx」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/yasinshaw/article/details/103307125

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章