iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
Software Development

From State Machine to XState系列 第 5

Day05 - 開始、結束與有限狀態機

昨天習得 事件轉移 的概念後,讓我們來思考實作這個 transition,還需要什麼東西?

transition('待付款', '收到帳款')  === '待發貨'
transition('站立', '按 B') === '跳躍'

或者說我們這個主體、狀態至轉移的過程,還欠缺什麼東西?

訂單:提交 → 待付款 → 待發貨→ 待取件→ 交易完成
角色移動模組:站 → 跳 → 站

1. 開始

以 RPG 遊戲的角色移動模組為例,玩家開始操縱角色前,一定要會有個初始狀態,可能是來自上次離線的紀錄(等級、hp,mp, sp, attack, speed..)或是初心者最開始的狀態。

而以電商訂單為例,訂單最開始一定會有提交階段吧,由消費者向廠商提出購買的意願、詢問是否有貨源等等,當有了這個最開始的條件,我們才能確認、有辦法繼續往後面處理一系列的交易流程。

所以這個主體也必須要有一個初始值,我們稱做初始狀態 (Initial State)

2. 結束

以 RPG 遊戲的角色移動模組為例,玩家開始操縱角色後,什麼代表著結束?可能是玩家決定登出、角色HP歸零死亡,遊戲破關等等...或者是玩家移動到一個安全的地方,然後把電腦繼續開著掛機,不會結束。

而以電商訂單為例,怎麼樣可以視一張訂單為結束?
可以是產品送達客戶後的交易完成、或是客戶決定取消下單、或供應商沒貨的交易取消、或是使用者忘記期限內付費的交易失效等等。

我們稱這個主體被結束時,所處的狀態稱作結束狀態 (Final State"s")

3. 有限狀態機 ( Finite State Machine )

所以我們大致觀察一直以來的這兩個範例需求中的一些特徵

  1. 他們都有一個初始狀態
  2. 整個實體、物件或是對象,都有一系列不同的狀態們
  3. 還有一系列不同的事件,可能會導致狀態轉移
  4. 還有一張紀錄著什麼事件配什麼狀態會發生轉移的地圖、對應表
  5. 有限數量的結束狀態( 0 - n 個 )

https://ithelp.ithome.com.tw/upload/images/20210920/20130721SCO6gzH9tL.png
by The Finite State of Reactive Animations

一個主體、物件底下所存在的狀態們、事件,以及轉換的這個旅程,我們稱作一個有限狀態機(Finite State Machine)。

至於為什麼狀態機前多了前綴字「有限」

我想可以用這句話理解: 因為要有 Transition 這張表的存在,必須記錄 什麼事件 + 什麼狀態 = 轉換後的狀態 ,因為要把它們列舉出來,前述的狀態與事件的數量就會是有限的。

首先簡單來幫大家再回顧一下為什麼從 Day01-Day05 有這一系列的探索與討論

原因便是我們在規劃一個物件、系統流程時,底下有太多不同種的狀態,還有各自的條件限制,為了滿足系統與規格的需求,假如我們只單純使用 if/else block 並設計幾個 flag isSomething/isOtherthing 隨著系統擴充、調整,可能會為我們帶來麻煩。

假設我的功能新增 也是繼續增加 if/else 或是增加 flag isC/hasD 等等,我們會面臨到,必須回去其他檢查舊有的 if/else block ,思考新增的狀態跟舊狀態有沒有什麼相依性、或是防禦 (Guard) 要處理,違反了開放封閉原則 ,專案程式碼也變得難以閱讀。

雖然上述的寫法很簡單、很快速,我們的程式碼也能非常自由的靈活運用,但代價就是過於自由,變得難以顧及整體。

那我們能不能犧牲一點自由?

限制你總體狀態的有哪些、可以有哪些事件存在,什麼事件配什麼狀態能進行狀態轉移 → 有限狀態機 ( Finite State Machine )

所以如果當你的需求是一個複雜狀態的情境時,在系統規劃上,你便可以考慮使用有限狀態機

參考文獻


上一篇
Day04 - 事件、狀態轉移
下一篇
Day06 - 根據需求畫出 Flowchart 或是 State Diagram
系列文
From State Machine to XState31

2 則留言

0
TD
iT邦新手 4 級 ‧ 2021-09-20 23:39:35

結束狀態 (Final State"s")

這裡特別強調 "s" 是指有多種結束狀態嗎?

Ken Chen iT邦新手 5 級 ‧ 2021-09-21 09:17:10 檢舉

5.有限數量的結束狀態( 0 - n 個 )

對,就是後面提到的,結束狀態可能會有 0 - n 個
有可能不會有結束狀態,也有可能有多個結束狀態

0
pjchender
iT邦新手 4 級 ‧ 2021-09-27 21:45:04

之前都沒想到這種思考角度

nextState = f(previusState, event)

我要留言

立即登入留言