Day13 - 解决状态大爆炸 - 1: Parallel States (平行式状态)

以昨天的例子而言,我们的 input 有 [Invalid / Valid]、[Disabled / Enabled]、[Changed / Unchanged],这 3 类型的特点

https://ithelp.ithome.com.tw/upload/images/20210927/20130721esiomcqiFn.png

让我们仔细观察一下

  • 假设有没有 Invalid 不影响会不会 Disabled;
  • 假设有没有 Invalid 不影响会不会 Changed;
  • 假设有没有 Disabled 不影响会不会 Changed...
    并且假如我们说这 3 类特徵任意搭配组合也都是合理的...
    也就是[ Invalid 且 Disabled 且 Changed] , [Valid 且 Disabled 且 Changed] 这种奇怪的组合都是合法的话。

透过这些假设,我们发现(或是我刻意制造)这三类型特点,互不相关,彼此是相互独立的、没有依赖的关系。

先不以开发状态机的角度思考,这个需求很自然的先想到可以将它拆成 3 组 Boolean Flag,存入 3 个变数(isValid, isEnabled, isChanged)

用变数 Boolean Flag 表达可能性的话

// 假设用不同 className 储存、辨别 Input style
let className = ''

if (isValid && isEnabled && isChanged) {
  className = ''
} else if (!isValid && isEnabled && isChanged) {
  className = ''
} else if (isValid && !isEnabled && isChanged) {
  className = ''
} else if (!isValid && !isEnabled && isChanged) {
  className = ''
} else if (isValid && isEnabled && !isChanged) {
  className = ''
} else if (isValid && !isEnabled && !isChanged) {
  className = ''
} else if (isValid && !isEnabled && !isChanged) {
  className = ''
} else {
  className = '' // (!isValid && !isEnabled && !isChanged)
}

看起来真不可口

用 状态大爆炸版 的 Finite State Machine 表达可能性的话

[Invalid / Valid]、[Disabled / Enabled]、[Changed / Unchanged]

可以列出以下

  • valid / enabled / unchanged
  • invalid / enabled / unchanged
  • valid / disabled / unchanged
  • invalid / disabled / unchanged
  • valid / enabled / changed
  • invalid / enabled / changed
  • valid / disabled / changed
  • invalid / disabled / changed

就像昨天提到的,在描述状态的可能性就已经极其复杂,只不过...至少用「状态」比用「 Boolean Flag 变数」的描述更明确(Explicity)指出、更有可读性(Declarative)一点点...。但这边都还没办法开始描述什麽东西能改变状态?!

什麽事件发生後,状态会发生改变?要怎麽描述?

今天要为大家介绍的就是平行式状态,我们可以将这三组特徵、变数视为『各自独立』的子状态(substate)

  • [Invalid ⇄ Valid] 是一组子状态机
  • [Disabled ⇄ Enabled] 是一组子状态机
  • [Changed ⇄ Unchanged] 是一组子状态机

因为这 3 组 子状态机彼此独立,我们将之视为平行世界、互不相干,我们称之「平行」

而这 3 组 子状态机组合而成的所有可能就是这个主体状态,也就是说 「Input」的状态 。

平行式状态的状态图

我们可以根据此画出平行的状态图
https://ithelp.ithome.com.tw/upload/images/20210928/201307217x4fU4EWAi.png

versus

https://ithelp.ithome.com.tw/upload/images/20210927/20130721uWTVRmuIor.png

相较於昨天画的 state diagram ,不管在「状态」或「事件」的描述是不是清晰多了?

小节

平行式状态使我们能

  1. 使我们能提炼、精致状态,将离散的行为拆分成独立的子状态机
  2. 允许状态间的独立性 (反言之,转移禁止跨越子状态机之间)
  3. 鼓励组合、组装(Composability)
  4. 避免状态大爆炸 ^^

参考资料

https://statecharts.dev/glossary/parallel-state.html
https://xstate.js.org/docs/guides/parallel.html
https://statecharts.dev/state-machine-state-explosion.html
https://xstate.js.org/docs/guides/hierarchical.html


<<:  DAY13:Fragment片段之实作

>>:  [DAY 23] Elo Rating

Day26 了解Hook

Hook是React在16.8中增加的新功能,和过往React Component架构相比,可以帮助...

Day 1 - [绪论] 长照小帮手的背景与动机

大家好,其实这个长照小帮手是我的论文题目,所以这系列的多文章,会有一大部分来自简化的论文内容,再加上...

Day 25:动态规划(dynamic programming)

动态规划也是一种演算法设计模式,常用来解决最佳化问题。它的方法是将问题(通常是递回地)分解成子问题,...

Day 7 - 文字使用方式

字体大小 相信大家以往在写 CSS 时,也有写过像这种 text-12、font-12 看起来很聪明...

Display - 金鱼都能懂的CSS必学属性

display 这个属性实在是一个太重要的属性了,要在一个篇幅中讲完其实是不可能的事情,它可以说是目...