我們目前所學到的狀態機已知,我們能透過 transition 限制狀態轉換的路徑
但現實情況下,很常有可能是,就算已經對的 state 跟 event 了,你還是希望加上某些條件或者判斷才能轉移狀態。
比如說開發一個電子報新聞後台,假如一篇新聞的生命週期需要經過『草稿』、『審稿中』、『發佈』、『下架』等,我們可以根據此設計成一個狀態機。
沒錯!理想的情況下,一篇新聞從 『審稿中』 → 『發佈』時,遇到「審核通過」的事件時,的確應該將新聞的狀態轉移到發佈。
但...,現實情況很常會希望,做更進一步的限制或檢查。比如說,只有相關權限人士執行這個操作才有效,或是必須經過特定檢核才能轉移到發佈的狀態...。
這時你就需要 Guard 在進入下一個狀態前,作為守衛,進行檢核判斷。
以下圖為例,一組登入的狀態圖,初始狀態是登入中,帶有一個資料儲存「登入錯誤的嘗試次數:Tries」,當 [Logging in] 要轉移到 [Logged in] 時,會遇到一個事件 [Valid Entry] ,同時還有一個 Guard 是 Tries 的次數要小於 3 ,當使用者的每次登入失敗時,Tries 會被加一,當 Tries 達到3時,就會轉移到 [Login Denied] 的狀態。
另外一組例子,一個水瓶或是馬克杯的狀態
一開始是『空的』,有「裝水」這個事件,每次要裝水時,都會當前水量 + 預計倒水量,有沒有超過容器最大容積
「裝水」可以一次裝滿,轉移到『滿水位』的狀態;或是每次都裝一點,轉移到『有部份水量』的狀態
但每次「裝水」事件都會檢查容量夠不夠。
最後『滿水位』時,配上「封蓋」的事件,可以把我們的水瓶或者是馬克杯『蓋上』
在這邊我們也可以稍微猜想一下 Guard 程式面的實作有哪幾種可能,可能會是個儲存 boolean 值的變數,可能是個會回傳你 true / false
的預測函式,也有可能像 JSON config 的樣貌。
Guard 也是用來解決狀態機在現實世界中可能遇到的問題,當你有想要做什麼限制、檢查,才能進到下個狀態的話,你可以使用 Guard
https://statecharts.dev/glossary/guard.html
https://xstate.js.org/docs/guides/guards.html
https://sparxsystems.com/resources/gallery/diagrams/images/state-machine-diagram-transition-guards-and-effects.png
Guard 的概念在權限檢查很常出現,不知道可以怎麼把狀態機也應用在公司的專案上(自言自語 XD)
讓我們一起繼續往後面看下去XD 我加油~~~