iT邦幫忙

2021 iThome 鐵人賽

DAY 16
0
Software Development

From State Machine to XState系列 第 16

Day16 - 快速回顧 Finite State Machine, State Chart + 淺嚐 XState

  • 分享至 

  • xImage
  •  

回顧 Finite State Machine

1. 什麼是一個 State ?

一個 state 是指某個 物件 / 實體 / 行為系統,在某個時機點 / 情況底下的型態、模式、狀況,但不是描述在這個狀況下所有的資料,比如在某些狀態下,可能會有無限的資料存在。
by XState - Concepts

範例

主體:水
狀態:固態、液態、氣態。


2. 什麼是一個 Finite State Machine ?

用來描述一個系統、物件或實體的行為的數學運算模型,在一個時機點下,只能有個狀態存在。

具有以下特點

  1. 要有一個初始狀態 (Initial State)
  2. 存在一些數量有限的狀態 (Finite States)
  3. 存在一些數量有限的事件 (Finite Events)
  4. 有一張表紀錄著 什麼事件 配 什麼狀態,可以轉移到另一個什麼狀態 (Transition Mapping)
  5. 存在一些數量有限的的結束狀態(可為 0 個)(Finite Final States)

範例

https://ithelp.ithome.com.tw/upload/images/20210926/20130721htU67KKipL.png

英文 中文
0. Entity / Object: Door 0. 主體:門
1. Initial State: closed 1. 初始狀態:關著
2. Finite States: closed, opened 2. 有限個狀態:關著、開了
3. Finite Events: open, close 3. 有限個事件:開門、關門
4. Finite Final States: N/A(0) 4.有限個結束狀態:不存在
5. Trasition Table:see below 5.轉移表:如下
Current State Event Next State
closed open opened
opened close closed
當前狀態 事件 未來狀態
關著 開門 開了
開了 關門 關著

3. 什麼是一個 State Chart ?

State Chart 是一位有名的數學家 David HAREL 提出在現實世界的複雜系統可以怎麼用一個不錯的視覺表達的形式(A VISUAL FORMALISM FOR COMPLEX SYSTEMS),簡單來說,就是 FSM 的加強版、現實生活版。

前面稍微介紹過 State Chart 的一些內容

  1. Action: 讓我們除了狀態轉移外,能實際執行相對的 side effect
  2. Hierarchical States: 為了避免狀態大爆炸,一個父狀態允許有多個依賴於父親的階層式的子狀態存在
  3. Parallel States: 為了避免狀態大爆炸,一個狀態可以包含多個互相獨立平行的狀態
  4. Guard: 一個守衛,除了對的事件 + 對的狀態之外,可以多一些條件判斷,來限制狀態轉移
  5. State Chart 還有一系列內容含 History State, Delayed Event, Delayed Transition etc...

4. 為什麼要用 Finite State Machine, State Chart

在一個複雜應用系統、使用場景中,明確(Explicitly)說出你的狀態能有哪些、狀態該如何轉移、限制你系統及狀態的可能性,避免系統狀態跑出例外或漏想清楚的地方( 可見Day1 Day2 Day6 Day7 這幾篇的比較 )


淺嚐 XState

1. 什麼是 XState ?

XState 就是一個以 JavaScript / TypeScript 實作 Finite State Machine 跟 State Chart 的套件。我們可以藉此方便快速建立我們 App 中的 State Chart 來作為狀態管理。

JavaScript and TypeScript finite state machines (opens new window)and statecharts (opens new window)for the modern web. by XState


2. 我的第一個 XState API - createMachine

前些日子我們也曾手動嘗試自己建立 2 個版本的 state machine ,但來到複雜的 state chart,我們還是依靠於別人寫好的火箭,不重複造輪子了。

還記得我們在 Day 09Day 10 有 2 個自製版本的 createMacine

[Day 09] 的 createMacinePure function - 無狀態版,要自己另外儲存 previousState, nextState

[Day 10] 的 createMacine有狀態版,會回傳我們一個 machine 的 object instance ,裡面記憶著當前的狀態(currentState)。

今天介紹的 XState API - createMachine 是我們 Day 09 製作的 Pure function - 無狀態版,只不過裡面吃的參數 machineConfig 可以處理得遠比我們的 util function 多,這裡的 machineConfig 是連 State Chart 的那些內容也可以一起寫入設定的(eg Action, Guard Codition, Parallel States, Hierarchical States)

範例

https://ithelp.ithome.com.tw/upload/images/20210926/20130721htU67KKipL.png

定義、設定 config

const doorMachine = createMachine({
  // Machine identifier
  id: "door",

  // Initial state
  initial: "關著",

  // State definitions
  states: {
    關著: {
      on: {
        // 可以用字串描述
        開門: "開了"
      }
    },
    開了: {
      on: {
        // 也可用物件描述
        關門: { target: "關著" }
      }
    }
  }
});

取得狀態、轉移狀態

const state0 = doorMachine.initialState;
console.log(state0);
const state1 = doorMachine.transition(state0, "開門");

Codesandbox 參考

https://codesandbox.io/s/xstate-01-tt1xr?file=/src/index.js


上一篇
Day15 - 守護你的狀態轉移 : Guard
下一篇
Day17 - XState 說為什麼可以選擇 XState?ft. 說文解字官網亮點
系列文
From State Machine to XState31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言