什麼是事件建模 Event Modeling?

基本概念

事件建模(Event Modeling)是一種描述系統的方法,展示信息如何隨時間變化的例子。具體來說,這種方式省略了瞬息萬變的細節,而着眼於在任何特定的時間點上的持久化存儲和用戶所見數據的變化。這些時間軸上的事件,構成了對系統的描述。

近年來,很多系統使用事件通過事件存儲數據庫或者使用特定方式使用常規數據庫構建了狀態和信息傳播的模塊。然而,大多數方法仍然依賴於通過 SQL 數據庫、文檔數據庫或者其他技術實現嚴格意義上的當前時間點信息的視圖。

對很多系統而言,特別是對於非小型系統而言,隨着系統複雜性的增加,變更成本將會隨着時間的推移難度指數級上升。與現有的設計和建模方式對比,事件建模可以在短時間內創建一個基礎藍圖,將返工工作量降到最低。

從過去談起

講故事自古以來就是人類能夠將知識傳遞給後代的方法,它在很大程度上依賴於我們如何存儲記憶 - 無論是邏輯的、視覺的、聽覺的還是其他的。這一點很重要,因爲這與信息系統的構建方式有相似之處。用具體的例子說明某物應該如何工作是一種常見的方式。這種方式可以在軟件開發的成功實踐中看到,如行爲驅動開發。這種方式很有效,因爲我們通過故事來溝通更有效。將它和講故事聯繫在一起,是一種保持社會信息的方式。我們的大腦是爲它而建的,而不是爲流程圖和其他格式而建的。而事件建模模型就是遵循這種講故事模式而建立的產品建模方式。

事件建模模式

時間線是最好描述故事主線的方式,對我們的系統而言,時間線也是描述我們系統核心部分概念的重要組成部分。我們可以通過在一條時間線上,系統從開始到結束,在沒有分支情況下應該做什麼方式展示我們系統的一部分功能。這就是一個典型的事件模型的組成。我們可以用這種方式跟蹤所有 UI 界面中字段值如何存儲和如何展示的。比如在上面的示例圖中,我們使用了 3 種不同模塊的內容和傳統的線框模型就展示了整個系統的模型。但是簡單性是我們重要的一個目標,因此我們只依賴於 4 種模式構建這種模型圖。

保持簡單性

當我們想採用某些做法或流程來幫助彼此理解和溝通時,它與個人爲熟練掌握這些方法而進行的學習量成反比。換句話說,如果我們可以更快的掌握一個名叫 X 的方法時,我們就可以更好的通過這種方式進行知識分享和互動;反之,無論這種方法多麼好,昂貴的學習成本總會搞砸一切。

當一本書是團隊中的必讀書目時,每個人都會說他們讀過;但事實上只有一半的人會真正讀過;這些真正讀過的人中一半的人會聲稱他們理解了這本書;而這些聲稱理解的人中只有一半的人真正的理解了這本書;而這些真正理解了這本書的人只有一半的人能夠使用它。

這就是爲什麼使用 3 個模塊和基於 2 個想法的 4 種模式進行事件建模。因爲這隻需要幾分鐘就可以將所有的東西向所有人解釋清楚。其他的學習則可以在實踐中進行。即便理解出現了不足和錯誤,也可以很快在實踐中得到糾正。

事件

假設我們想爲連鎖酒店設計一個酒店網站,讓我們的客戶可以在線預訂房間,並讓我們安排清潔和任何其他酒店問題。我們可以顯示在該業務的年度時間線上存儲了哪些事件。我們可以假裝我們已經有了這個系統,然後問自己隨着時間的推移存儲了哪些事件。

線框圖

讓我們看一下在圖片的最上面的部分的第一個模塊。爲了讓講故事這個事情更加可視化,我們可以在頂部顯示功能的線框圖或者網頁模擬圖。這也可以被具象化爲具體的泳道圖,以方便不同的人(也可以是系統)與我們的系統進行互動。這裏一些自動化的內容可以用齒輪表示,同時說明系統正在做什麼。通過這種方式,我們可以非常容易的展示出系統需要實現的功能列表,執行流程和項目完成標記。這裏的圖是示例了一個酒店的預訂、支付和通知系統的過程,我們可以重點關注一下所有相關高亮顯示的內容。

藉助這個模塊,我們可以很方便的和設計師一起溝通設計系統,當然,這裏需要注意在設計中,兩個重要的內容需要添加到整個設計中:用戶所擁有的權限和用戶可以獲取的信息。

命令

大多數信息系統必須給用戶一種影響系統的狀態的能力,而這種能力就是命令。在我們的例子中,我們必須允許房間預訂改變系統狀態,這樣我們就不會發生超額預訂情況。當那個人在未來的預訂日期到達時,他們就有一個爲他們準備的房間。

改變系統狀態的意圖會被封裝在一個命令中。相對於簡單地將表單數據保存到數據庫中的一個表中,這可以讓我們以非技術性的方式來顯示意圖,同時允許任何實現 - 儘管我們可以看到某些方法更具優勢。

從 UI 和 UX 的角度來看,這就是一個 "命令響應式用戶界面",對幫助製作可組合的 UI 大有幫助。使用這種模式,從技術和商業的角度來看,交易的界限就更清楚了。以酒店入住爲例,酒店的客人要麼登記成功,要麼沒有。

當命令成功的前提條件有細微的差別時,它們會在 "Given-When-Then" 風格的描述方式中進行闡述。這種方式也是行爲測試模式慣用的描述方式,也是一種成功的講述故事的方式。實際執行過程中,可能會有幾個這樣的故事來說明一個命令如何能成功執行和不能成功執行。

這裏我們可以用一個例子來描述一下:

Given:我們已經註冊並添加了一個支付方式

When:我們試圖預訂一個房間

Then:一個房間被預訂了

這種描述方式也通常被叫做 “安排、行動、斷言”,在 UI/UX 的世界中,也被稱爲 “情景、統計、價值”。在圖中我們也可以發現,所有的命令都是用藍色進行標記的。

視圖(或者叫讀模型)

任何信息系統的一個重要能力是將系統中保存的狀態告知用戶。我們的酒店客人需要知道他們感興趣的某些類型的房間在哪一天可以入住。這通常有很多種情況,需要支持信息系統的多個模型。

隨着這些新事件的存儲,系統中的視圖也會一直變化。在我們的酒店系統中,這個日曆視圖隨着影響庫存的新事件的發生而被更新。其他視圖中清潔團隊可以在客戶離店事件存儲後在其他視圖中看到房間已經可以被清理了。

指定視圖的行爲方式與我們指定接受命令的方式非常相似,但有一處不同。視圖是被動的,並且不能在事件被存儲到系統中之後撤銷事件。

舉個例子:

Given:酒店設置了 12 間海景房,海景房從 4 月 4 日到 12 日被預訂

Then:日曆上應該顯示除 4 月 4 日到 12 日以外的所有海景房的日期

從上面圖中我們也可以注意到,所有的讀都是用綠色進行標記的。

集成

我們剛剛介紹了描述大多數系統所需的 4 種模式中的前 2 種模式。系統可以從其他系統獲取信息並且將信息發送到其他系統。強迫這 2 個模式成爲前 2 個模式的擴展並共享相同的空間是很誘人的選擇。然而這會讓交流變得更加困難,因爲它們沒有人類可見的方面,並且需要一些更高級別的模式。

翻譯

當我們有一個爲我們提供信息的外部系統時,將這些信息轉換成我們自己系統中的更熟悉的形式會很有幫助。在我們的酒店系統中,如果選擇讓我們的清潔人員反應更加靈敏,我們可以從客人的 GPS 座標中獲取事件。我們不想使用經度和緯度對作爲事件來指定我們系統中的先決條件。我們寧願選擇對我們有意義的活動,例如 “客人離開酒店”、“客人回到酒店房間”。

常,翻譯很簡單,可以表示爲從外部事件中獲取信息的視圖。如果我們不將它們用作測試的任何 “Given” 部分,則它們存儲在該視圖模型中的值僅在我們的狀態更改測試中的命令參數中表示。

自動化

我們的系統一般都需要與外部服務進行通信。當我們酒店的客人在退房時支付住宿費用時,我們的系統會調用付款處理程序。我們可以通過系統中某個處理程序的 “待辦事項列表” 的概念來了解這是如何發生的。這個待辦事項列表顯示了我們需要完成的任務。例如,我們的處理程序會不時查看該列表(可能是幾毫秒或幾天)並向外部系統發送命令以處理付款。然後將來自外部系統的回覆轉換爲我們存儲回系統中的事件。通過這種方式,我們將系統中使用的構建塊保留爲對我們有意義的東西。

我們通過在具有線框的藍圖頂部放置一個處理程序來展示這一點。這表明這些東西在屏幕上無法看到但在後臺發生。由於需要完成後臺任務,用戶可能期望旋轉圖標提示延遲。此規範的形式爲 “Given:要執行的任務的視圖,When:每個項目啓動此命令時,Then:這些事件會返回。”

實際上,這些可以通過許多不同的方式實現,例如隊列、響應式或實時構造。它們甚至可能是我們使用的待辦事項列表。這裏的目標是傳達我們的系統在需要影響外部時是如何與之溝通的。

落地實現

事件建模分 7 個步驟進行。我們已經解釋了最終的目標。因此,讓我們倒退到開頭,展示如何建立起藍圖。

頭腦風暴

我們讓某人解釋項目的目標和其他信息。然後,參與者設想系統的外觀和行爲是什麼樣的。他們寫下所有他們能想象到的發生的事件。在這裏,我們只需要明確改變了狀態的事件。這些所有的事件一定要意味着某些狀態的變更,如果沒有發生變更,那麼他們就不是事件。比如,有人會說出 "客人查看了房間的可用日曆",那麼這個就不是事件。

闡述劇情

現在的任務是用這些事件創造一個合理的故事。因此,它們被排列成一條線(也就是時間線),每個人都檢查這條線,以瞭解這條時間線作爲按順序發生的事件是合理的。

製作故事

接下來,需要製作故事的框線圖或模擬圖,用可視化幫助初學者上手。更重要的是,每個領域都必須被表示出來,這樣系統的藍圖就可以從用戶的角度來表示信息的來源和目的地。

UX 並行

線框圖一般被放在藍圖的頂部。如果有超過一個用戶的話,它們可以被分成獨立的泳道,以顯示每個用戶看到的東西。這裏需要注意我們需將系統的每個變化轉化爲藍圖的單獨一列,因此屏幕不能出現垂直重疊的情況。不同的排序可以顯示在各種詳情中。如果它是系統的核心或非常重要的交互,則需要在藍圖中添加備用的工作流程。這是顯示部分的最後一步,但如果有幫助的話,可以提前完成。

鑑別輸入

從前面的部分我們看到,我們需要展示我們如何讓用戶改變系統的狀態。這通常是我們引入藍框的步驟。每次由於用戶的操作而存儲了一個事件時,我們通過一個命令將其與 UI 聯繫起來,如果是一個網頁程序,這個命令展示了我們從屏幕上獲取或隱式的從客戶端狀態得到的信息。

鑑別輸出

再次回頭看一下我們的藍圖目標,我們現在必須通過視圖(又稱讀模型)將通過存儲事件積累的信息鏈接到用戶界面。這些可能是像酒店系統中的日曆視圖一樣的東西,當用戶想要預訂房間時,它將顯示房間的可用性。

應用康威定律

現在我們知道了所有的信息是如何進出我們的系統的,我們可以開始研究將事件本身組織成泳道。我們需要這樣做,以便讓系統的模塊作爲一組獨立團隊可以擁有的自主部分而存在。這允許專業化發生在我們控制的水平上,而不是脫離團隊的組成。詳見梅爾康威的康威法則。

精心設計場景

每個工作流程步驟都與一個命令或一個視圖 / 讀模型相聯繫。前面已經解釋了這些規範。我們如何制定它們,仍然是與所有參與者合作進行。一個 Give-When-Then 或 Given-Then 可以在快速的構建的同時被多個角色進行審查的。這使得傳統上由專門的產品負責人以文本格式單獨完成的用戶故事寫作,可以在極短的時間內以可視化的方式協作完成。更爲關鍵的是,每個定義都與一個命令或視圖相關聯。

完整性校驗

事件模型應該有每一個字段的說明。所有的信息都必須有一個起點和一個終點。事件會促進這種轉換,幷包含必要的字段來實現這一目標。這種嚴格性是使用該技術的最大好處。

這方面的一個變種是,我們不做這個最後的檢查,在某些情況下,這也是可以的。

項目管理

如果完成的足夠良好,我們製作出的是一組包含每個工作流程所有場景定義的足夠小的組合。他們可以直接轉化爲開發人員的開發內容和測試內容,並且只與約定部分和相鄰工作流程相耦合。

明確的約定

許多項目管理、業務和協調問題都因爲我們對工作流的某一步驟開始時的信息形狀和完成時的數據形狀做了明確的約定而得到緩解。這些事前和事後的條件是允許工作在相對孤立的情況下完成,並在之後按照設計與相鄰的步驟結合在一起。

平坦的成本曲線

使用事件建模的最大影響是可以建立一個平坦的成本曲線。這是由於建立每個工作流程步驟不受其他工作流程開發的影響。需要理解的一件事是,如果一個工作流程步驟使用了相同的命令或視圖,那麼它就可以被認爲是在事件模型上的重複。

這一點的影響是非常深遠的,因爲它是將軟件開發重新變爲工程實踐的原因。它使創建一個信息系統的工作像建造房子一樣。功能可以以任何順序被創建。傳統的開發不能依靠估算,因爲功能是否在項目的早期和後期所需的工作量會隨着系統的複雜度而被影響。重新確定工作的優先次序使得以前的估算變得不可靠。

真正的完成就是要正確的完成

當一個工作流程步驟被實現後,實現任何其他工作流程步驟的行爲都不會導致需要重新調整這個已經完成的工作流程步驟。這也是恆定特徵成本曲線能夠實現的原因。

沒有估算的估算

有了恆定成本曲線,一個團隊的開發可以簡單地通過許多功能在一段時間內進行衡量。這是一種相對公平的方式,可以憑經驗確定團隊的速度。這些數字在之後可以被用來確定未來項目的範圍、進度和成本。

關於測試驅動開發

這是行業內採用敏捷實踐帶來的影響,就像將創可貼貼在缺乏設計的核心問題上。因爲現在每個團隊需求的範圍都是按工作流程步驟進行的,所以 TDD 的重構步驟不會影響事件模型中的其他工作流程步驟。當我們沒有事件模型的時候,重構就可以不受限制地進行,以前完成的工作片段就需要進行調整。已經完成的工作越多,在我們構建解決方案的過程中,每一個新增加的工作都會被審查和調整。

項目外包

恆定成本曲線給了制定固定成本項目的機會。一旦有了一個團隊的開發速度,你就可以明確團隊的軟件的成本。有了這個數字,你現在就可以爲你願意給外包廠商完成的每個工作流程步驟的報酬定價了。

產出保證

由於每個工作流程步驟都受到保護,不受其他工作流程步驟的影響,因此,任何缺陷都將由誰爲它們提供非計費工作來保證。因此,如果一個外包商只是爲了快速完成更多的可計費項目而做得不好,他們就必須讓接下來的工作時間專門用來修復之前已經完成的工作的缺陷。這就平衡了他們的有效工資率,因爲他們不是在做新的應交付的工作。

這可以通過不同的績效檢查點來提供這些指標,在員工參與的過程中長期進行下去。

由於有效薪酬可以根據個人的能力進行自我調整,這也是一種讓新員工入職的方式,在他們處於試用階段的時候,對他們進行公平的支付。這種從合同到僱傭的過程消除了技術職位的主觀和基本無效的面試過程。

確定優先順序

在不改變每個項目的估計成本的情況下,在時間表上移動工作,即哪些步驟要先實施。這確保了工作的優先次序對總成本沒有影響。恆定成本曲線的要求是允許這種重新確定優先次序的 “敏捷性”。

變更管理

當計劃改變時,我們只需調整事件模型。這通常是通過直接複製當前的內容並進行調整來實現的。這樣,我們就可以直觀的看到差異在哪裏。如果一個事件中加入了新的信息,這就構成了創建該事件的工作流程的新版本。視圖也一樣。如果這些還沒有開發,那麼這就不會改變我們的計劃。如果它們已經開發了,它們就會給我們的開發計劃增加另一個實現單元,它被認爲是對原有流程的一種替換。圍繞這一點還有一些規則。最終的結果是爲變更管理提供一個明確的指南。

安全性

有了事件模型,該方案可以準確地顯示敏感數據在哪裏,同樣重要的是,敏感數據何時越界。在傳統的審計中,與員工面談的次數很耗時,而且有可能錯過重要的領域。當應用程序有一個事件模型作爲參考時,安全問題就能夠得到最有效的保障。

遺留系統

大部分組織所面臨的情況是大多數系統已經存在了。處理一個因爲複雜和缺乏理解而難以管理的系統的主要方法是重寫它或在它運行時重構它。這兩種做法的代價都是非常昂貴的。

其實還有第三個風險較小的選擇。凍結舊系統。在適當的支持下,團隊可以不再考慮變更現有的系統。相反,處理錯誤和增加新的功能是作爲 sidecar 方式來完成的。

可以從舊系統的數據庫中收集事件,並製作該狀態的視圖–採用前面描述的翻譯模式。用戶行動的 Y 型閥重定向可以在側面解決方案中增加新的功能。一個修復了一個錯誤的例子(注意,我們採用了外部集成模式,並對舊系統進行了擴展,增加了資料圖片,如圖。)

這種模式可以讓團隊停止將精力浪費在現有的系統上,並能夠通過實現事件模型的模式解除遺留系統對快速交付價值的阻礙。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/OyplRWc8MaBVRaCa46NNPQ