在 .NET 中使用有限狀態機實現工作流建模 - Lloyd

banq發表於2022-05-19

希望這篇文章能幫助你瞭解複雜和深度巢狀的條件程式碼的缺點,併為如何編寫更容易理解和維護的程式碼帶來新的視角:
  • 解釋了複雜且深度巢狀的條件程式碼的問題,因為它需要匹配域模型而很常見
  • 介紹了狀態機的概念,以及它如何成為降低複雜性和使某些狀態不可表示從而減少引入錯誤的能力的解決方案
  • 區分公共 API 和文件的內部實現細節
  • 建立了工作流程圖並將其轉換為程式碼,同時強調了業務分析師/領域專家參與其中的必要性
  • 使用集中式錯誤處理機制處理無效轉換
  • 舉例說明如何使用 FSM 進行單元測試程式碼


需求問題
想象一下,一份檔案在傳送給客戶之前需要被 "批准"--檢查從語法和拼寫錯誤到商定的服務和價格等任何東西。然後,一旦它被批准,它就會被髮送給客戶。客戶必須批准、拒絕或要求修改。無論他們選擇哪種方式,檔案都會被送回給審批者作進一步審查。這樣一直持續到檔案完成,並且每個利益相關者都批准了它。

讓我們做一些近似的數學計算,看看這個看似簡單的工作流程會有多少個步驟或狀態。

  • 在它被批准或傳送給客戶之前,它顯然處於某種狀態。我把這稱為 "草稿"。
  • 它必須得到內部利益相關者的批准或要求修改。
  • 如果要求修改,那麼它就會進入自己的一套狀態。
  • 客戶批准該檔案。
  • 客戶拒絕該檔案。
  • 法律團隊批准該檔案。

以此類推...
這已經是6個以上的狀態了,但還有很多。狀態越多,工作流程就越複雜。如果我們試圖用程式碼來模擬這個工作流程,我們很快就會有幾十個甚至幾百個標誌來代表 "當前 "狀態。這還沒有考慮到帶有額外資訊的狀態,比如 "更改請求"。"改變標題"。此外,這甚至沒有考慮到可以同時設定的標誌的數量。
  • 在 "狀態 "和 "步驟 "之間沒有明確的區分--例如,一些步驟可以導致相同的狀態。
  • 一個新的功能可能會對程式碼產生很大的影響--也可能根本就沒有。沒有簡單的方法可以知道。
  • 每一個新的狀態都會增加標誌的排列組合的數量
  • 即使有單元測試,程式碼仍然很複雜,難以維護
  • 隨著更多狀態的加入,錯誤也在悄悄出現,重構也變得更加困難。
  • 沒有遵循使非法狀態無法呈現的概念--無效的狀態太容易被意外地變成可能,導致業務邏輯的缺陷。如果我們能儘可能多地轉移到型別系統中,我們應該這樣做。
  • 所有這些因素很快就會導致程式碼不再符合領域的情況



有限狀態機的解決方案
可能有無數的解決方案,但我要為這個 "文件工作流 "問題提出的解決方案是使用一個有限狀態機。首先,對有限狀態機進行正式定義。

有限狀態機(FSM)或有限狀態自動機(FSA,複數:自動機),有限自動機,或簡單的狀態機,是一種計算的數學模型。它是一種抽象的機器,在任何時候都可以準確地處於有限數量的狀態中的一種。FSM可以根據一些輸入從一個狀態改變到另一個狀態;從一個狀態到另一個狀態的改變被稱為轉換。一個FSM由其狀態列表、初始狀態和觸發每個過渡的輸入來定義。
- 維基百科

FSM是一個 "通用 "概念,實際上可以在任何地方使用,特別是數學、電子工程/嵌入式系統、科學和軟體工程。
在這個特定的案例中,我們用它來模擬軟體中的 "檔案工作流程",以取代不必要的複雜和巢狀的邏輯狀態。
還值得指出的是,FSM可以被用來為廣泛的領域建模。例如,使用者介面也可以用它們來實現,原因與我之前列舉的完全一樣;管理複雜性,使狀態和轉換更加明確。

記住,建立FSM的第一步是弄清所需的狀態和轉換。僅僅這一步就是讓業務分析師/領域專家/產品團隊/任何人都能參與進來的絕佳機會。這也將迫使我們進行一些前期設計,以確保程式碼與領域正確匹配。

相關文章