今天先来针对第 3 点改进,我们用到很多 switch case,回顾一下状态机的定义,一个状态机描述一个实体、对象,根据这点,我们能不能据此做点抽象化呢?既然说状态机有个对象,如果我们尝试着直接用 object 来描述看看呢?
首先一样要有个初始状态
const machineDef = {
initialState: "站姿、静止", // 初始状态
};
接着还有状态机底下的所有状态
const machineDef = {
initialState: "站姿、静止", // 初始状态
// 所有状态
states: {
"站姿、静止": ?,
"站姿、移动": ?,
"跳跃中": ?,
"俯卧、静止": ?,
"俯卧、移动": ?,
},
};
接着状态之後该放入什麽东西呢?我们知道至少还有个转移,nextState = transition(previusState, event)
,转移是需要状态、事件一起作为输入。
所以上面的 ? 是否可以放入一个 mapping 来存放 event
跟 nextState
的关系。
const machineDef = {
initialState: "...", // 初始状态
// 所有状态
states: {
"previusState1": mapping1,
"previusState2": mapping2,
"previusState3": mapping3,
},
};
一般 mapping 的实作常见可以使用 function (如果放在物件的会就是 method),然後该 function 里面可以再用 switch/case
或 if/else
实作,但...回头来看今天的初衷,就是要避免 switch/case
。
所幸我们想到,mapping 也可以透过 object literal 替代
所以我们就决定采用 object literal 来制作 event
跟 nextState
的对应关系(mapping)吧!
「事件」这两个字,让我们回想 JavaScript 如何处理、对待事件,以按钮 button 为例,<button onclick="">点我啊~</button>
,我们会对处於被动、等待、监听的状态时,通常会使用 on 这个前缀字 (如同 onClick, onSubmit, onFocus...)
那就尝试在每个 state 下,建立一个名为 on 的 object literal ,里面装有所有的 event
跟 nextState
的关系(即 transition mapping),对应关系的 key / value 怎麽配? previusState
要配 event
,既然前面已经有 previusState1
再加上我们又使用 on 这个前缀字,想必这个 mapping 的 key 必定是使用 event
,而 value 就是剩下来的 nextState
我们知道
const machineDef = {
initialState: "...", // 初始状态
// 所有状态
states: {
"previusState1": on:{
"event1": "nextState1",
"event2": "nextState2",
},
},
};
接着要回来继续实作了,为了简单看到 previusState
, event
跟 nextState
,彼此之间的关系,我们再度呼叫 State Diagram 出来~~~
const machineDef = {
initialState: "站姿、静止",
states: {
"站姿、静止": {
on: {
跳跃: "跳跃中",
开始移动: "站姿、移动",
卧倒: "俯卧、静止",
},
},
"站姿、移动": {
on: {
停止移动: "站姿、静止",
},
},
跳跃中: {
on: {
降落: "站姿、静止",
},
},
"俯卧、静止": {
on: {
起身: "站姿、静止",
开始移动: "俯卧、移动",
},
},
"俯卧、移动": {
on: {
停止移动: "俯卧、静止",
},
},
},
};
如此可读性是不是看起来比较提升呢?也大幅减少程序码行数,省掉不必要的 switch / case
那今天针对第三点做了改进
3. 用双层 switch case 好像比较不好读,感觉也不太好重复使用
这个 object 看起来就像是 state Machine 的定义一般,那我们可以怎麽操纵这个物件呢?
关於第二点
2. 当 state 跟 event 都是直接使用字串,很容易打错、出现 bug ,所以想要用常数保护起来
我们可以把 object 的 key 另外再用 const
储存成常数,或是使用 TypeScript 的 enum
剩下第一点,还有第三点当中的重复使用(这里还没多做解释)
1. State Machine 不完备,没有一个变数能帮我记忆当下的状态是什麽,我在使用 transition 时还要另外用一堆变数来储存 state ,感觉不好维护、也不好维持程序码的连贯性
我们可以制作一个 function 然後将 machineDef
这个物件 作为 input,明天就来跟大家分享怎麽建立这个 function!
>>: 【Day 10】 讨论 Data Analytics Pipeline - Google Analytics on AWS (整体)
简介 Go 是由 Google 开发的程序语言,於2007发起,在2009正式推,2012年发布第一...
NPM是Node Package Manager的缩写,中文直接翻的话就是Node包管理工具, 比较...
最近遇到最大的困扰是在实际工作上遇到的情况 越来越难找到教学或是sample可以做参考而解决 还有就...
优良部份1~5 1. 宽松型别(loose typing)及 易转型 https://codepen...
串接API 相信很多时候开发程序不是只有自己开发就可以了,不论是公司外还是公司内部都有打Api的需求...