iT邦幫忙

2021 iThome 鐵人賽

DAY 3
0
Software Development

From State Machine to XState系列 第 3

Day03 - 個體、對象以及狀態

小回顧

Day01 - 緣起:怎麼了?為什麼?如何掌握過於自由的程式碼?

訂單RPG 角色的移動,這 2 個例子,描述在複雜的軟體應用、系統中,會面臨的挑戰。
以及我們嘗試如何去克服這個困難

  • 透過儲存 boolean flag 進變數,記憶狀態
  • 透過一系列 if / else 判斷狀態、進行防呆)

Day02 - 觀察:自由的程式碼?有什麼蛛絲馬跡、現象?

解釋了 Day1 這個解決方案帶來了什麼困擾及難題

  • 狀態不具描述性、可讀性低
  • 違反開放封閉原則
  • 透過一系列 if / else 判斷狀態、進行防呆,當新增、修改功能時
    1. 要回去改動舊功能的程式碼
    2. 每新增一個狀態 flag ,除錯複雜度就大幅提升
    3. 狀態描述性下降、可讀性降低
    4. 溝通成本提升
    5. 必須注意邏輯之間的連動性、相依性
    6. 容易漏思考東西
    7. 容易產生冗余的邏輯語句
  • 換個角度觀察
    1. 獨立的狀態
    2. 舊狀態 → 新狀態,有明確的轉移路徑

1. 個體、對象

今天我們就要藉著這個新的角度下去討論,接續之前的兩個例子

1.RPG 遊戲的角色移動
2.交易系統的訂單進度

我們可以發現這兩個商業需求其實都是針對一個個體、實體(entity)或是物件(object)出發

主體 : 訂單

訂單進度是針對「訂單」進行追蹤,不同的進度會採取對應的行動。

主體 : 角色

同樣 RPG 角色中,我們的前進、後退、跳躍、匍匐這些行為,也都時針對玩家選取的「角色」操縱。

2. 狀態(state)?狀態(status)?

前面兩天都有提及狀態一詞,但我們還沒有對這個字有嚴謹的定義。

英文中的 state 及 status 都被翻譯為狀態,既然我們要研究的項目是:有限狀態機(Finite State Machine),我想我們有必要對「狀態」一詞進行釐清。

State: the particular condition that someone or something is in at a specific time.
Status: the situation at a particular time during a process.
by What is the difference between state and status?

state: the physical or mental condition that someone or something is in
status: a situation at a particular time, especially in an argument, discussion etc.
by StackExchange: "Status" vs. "state"

state表示一个确定的状态集中的某个状态(比如水的三态)
status表示一种笼统的情形(比如你的生活状态、工作状态),不存在确定的状态集。
by 知乎:程序代码中,怎么区分status和state?

綜合以上 3 組解釋,我們可以發現
狀態(state):比較偏向實際、實體的狀況或條件 (condition)。比如:水的三態,氣態、液態、固態
狀態(status):比較偏向一段期間的情況或形勢 (situation)。比如:冷戰狀態、工作狀態

State 一詞,在 Wiki (Computer Science)中的解釋

在 IT 或 CS 的領域中,如果有一個系統被設計來記憶先前的事件、使用者的互動等。這個被記憶起來的資訊,我們稱為狀態。而我們也稱這個系統是有狀態的(stateful)。

所以在前面兩個例子中,我們必須透過 flag 記憶訂單目前所在階段是什麼、才能根據此採取對應的行動;
RPG 角色的操控,也需要記起上一個行為是什麼,來決定下個行為,是不是合法的(俯臥不能直接跳起)

因此前述所指稱的「狀態」會比較趨近英文中的 "State",在這邊要跟讀者們界定,在本系列文中的「狀態」一詞,除非有另外特別解釋,否則皆應指為 "State" 。

3. 物件(Object)

在第 1 點的對象、實體或是物件,解釋完 State 之後,也想在此釐清

在 CS 的領域裡,Object 可以是一個變數、一種資料結構、一個函式、一個方法,換句話說,是一種儲存在記憶體裡面的值,被識別符(identifier,這裡我們比較常聽的是 key 或是 property name 等)參照
by Wiki:Object(computer science

真實世界中的物件都有 2 個特徵,他們都有狀態(state)及行為(behavior),比如狗有狀態(姓名、顏色、品種..)及行為(汪汪叫、搖尾巴...)
by Oracle - Java document :What Is an Object?

我想,以目前所知,現在所指的物件、主體、個體或對象,是會比較關注在這個 Object 底下的狀態;一個主體底下包含的各種狀態。(角色的狀態是跑、跳、匍匐著等)

前一天最後觀察到的重點

  • 換個角度觀察
    1. 獨立的狀態
    2. 舊狀態 → 新狀態,有明確的轉移路徑

能不能直接使用以下的程式碼?不要像第一天還要回頭做過多的防呆檢查...

if(state == '跳躍中')  // 畫出跳躍
if(state == '匍匐中')  // 畫出匍匐

因為狀態與狀態間是彼此獨立的(玩家不能同時是跳躍中跟匍匐中),而且狀態轉移有明確的路徑。

如果是匍匐中,下一個狀態就不能是跳躍中,只可以是站立

我們能不能設計一個函式讓狀態間彼此不相干擾

let nextState =  f(previusState) 

假設我們設計出這個 function 之後,能明確切分 state 跟 state 間的關係,也讓我們不必再回去原本狀態底下添加 if/else 防呆,但...

我們發現其實還有個不足之處,就像是 Oracle 對物件的定義是 「狀態」及「行為」。我們發現這個狀態的轉移呀,不單單只依靠 previusState

舉例而言,我們的規格書說

  • 按下 ⇦、⇨ 可控制玩家移動
  • 按下 B 是跳躍
  • 長按 ⇩ 是匍匐前進 → 放開 ⇩ 是起身

除了 previusState 之外,我們還必須注意操縱者的「行為」,或是說 監聽這些 keyboard (按鍵)的「事件」。

所以說那我們明天就繼續來探索這個世界或是行為吧


小節

  • 狀態:如果有一個系統被設計來記憶先前的事件、使用者的互動等。狀態是指這個被記憶起來的資訊。比較偏向實際、實體的狀況或條件 (condition)。比如:水的三態,氣態、液態、固態
  • 物件:物件都有 2 個特徵,他們都有狀態(state)及行為(behavior),比如狗有狀態(姓名、顏色、品種..)及行為(汪汪叫、搖尾巴...)
  • 狀態轉移的函式 nextState = f(previusState) 及其不足之處。

參考文獻


上一篇
Day02 - 觀察:自由的程式碼?有什麼蛛絲馬跡、現象?
下一篇
Day04 - 事件、狀態轉移
系列文
From State Machine to XState31

1 則留言

0
TD
iT邦新手 5 級 ‧ 2021-09-18 14:54:50

在 CS 的領域裡,Object 可以是一個變數、一種資料結構、一個韓式、一個方法、一個函式、一個方法,換句話說,是一種儲存在記憶體裡面的值,被識別符(identifier,這裡我們比較常聽的是 key 或是 property name 等)參照

多了一個韓式 :)

Ken Chen iT邦新手 5 級 ‧ 2021-09-18 16:06:07 檢舉

感謝,一定是半夜鍵盤肚子餓了/images/emoticon/emoticon01.gif

Ken Chen iT邦新手 5 級 ‧ 2021-09-18 16:06:08 檢舉

?感謝,一定是半夜鍵盤肚子餓了

我要留言

立即登入留言