Day10 - 实作一个状态机 - 3

我们昨天透过一个 object 描述一个状态机的定义,还记得前天我们的 switch / case 做出的 transition function 吗?transition function 是一个 纯函式(pure function),我们还缺少一个东西来储存当前的状态。

State Machine 不完全,没有一个变数能帮我记忆当下的状态是什麽,我在使用 transition 时还要另外用一堆变数来储存 state ,感觉不好维护、也不好维持程序码的连贯性

试着思考看看 有个 function 叫做 createMachine ,当我们把 状态机的定义 machineDef 丢进去,他就可以回传给我们一个能储存状态的状态机

someMachine = createMachine(someMachineDef)

那我们这个 someMachine 会需要有哪些东西?

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

[x] Initial State,
[x] States,
[x] Events,
[_] Transition,
[_] Final States (可能没有)

上面 [x] 这些东西已经在昨天被我们写进 machineDef ,那我们应该还缺的是 transition function 跟能储存当下状态的 Current State

为了储存状态 Current State,程序开发中,目前所知具有状态性,能储存状态的值也是「物件」,所以我们决定采用物件,这个物件会依照 machineDef 当作 configuration。

假设我们希望 someMachine.state 可以拿到当前状态, someMachine.transition('事件') 可以转移状态,所以我们的透过 function 回传一个物件,实作可以长这样

function createMachine(machineDef) {
  return {
    // 初始值是 initialState 我们透过这个 object 储存 state
    state:machineDef.initialState,  
    // 实作  transition
    transition(event){
       ...
    }
  }
} 

那新版的 transition 该怎麽实作,先来看看我们手上有什麽材料,一起来看看昨天的 machineDef

const machineDef = {
  initialState: "站姿、静止",
  states: {
    "站姿、静止": {
     on: {
        跳跃: "跳跃中",
        .....

我们可以从 machineDef.states[state] 拿到当前状态下所有事件对应该的转换,下个也就是我们昨天说的那个名为 on 的 transition mapping

所以继续往下走,接着可以透过 machineDef.states[state].on[event],取得发生某个的事件後要转成的状态。

所以我们的 transition 应该可以这样实作,拿到物件的 Current State ,以及使用者要执行的事件 Event

   transition(event){
       const nextState = machineDef.states[this.state]?.on[event]
       this.state = nextState
       return this.state
    }

然後可能查找失败,当我们拿不到值,transition 不能正确转换、或说不应该转换,此时,我们应该就要维持原本的状态

因为 nextState = transition(previousState, event)的 previusState, event,只要其中一个是不符的话,代表我们不能改变状态。

   transition(event){
       const nextState = machineDef.states[this.state]?.on[event]
       if(nextState){
         this.state = nextState
       }
       return this.state
    }

如此我们就完成了一个简单的 state machine

function createMachine(machineDef) {
  return {
    // 初始值是 initialState 我们透过这个object 储存 state
    state:machineDef.initialState,  
    // 实作  transition
    transition(event){
       const nextState = machineDef.states[this.state]?.on[event]
       if(nextState){
         this.state = nextState
       }
       return this.state
    }
  }
}

https://ithelp.ithome.com.tw/upload/images/20210925/20130721Jz1TOcymQG.png


<<:  【Day25】React Class Component 生命周期简单介绍

>>:  Day13 vue.js实现简单的注册功能ep1

# iOS APP 开发 OC 第十八天,MRC 实作

tags: OC 30 day 为什麽放这张图?应为我觉得MRC就像是古老的仪式。既然MRC已经没什...

Day 27 Celery

终於要进入 Celery 这个主题了,还记得我在 Day 24 说过介绍 Flask-Mail 的另...

DAY 15- 《公钥密码》-ECC

高中听过有人念ㄙㄨㄟˊ 圆形,我当时真是害怕极了。 --- 椭圆曲线 (Elliptic curve...

Perspective 3D 成像

大家好,我是西瓜,你现在看到的是 2021 iThome 铁人赛『如何在网页中绘制 3D 场景?从 ...

[DAY2]SQL新手的懒人笔记

接续上一次的内容,今天一样会用较为简单的叙述去介绍与分享SQL的简易语法与函数。(大写为内建语法) ...