Day04 - 事件、状态转移

我们必须记忆一个主体的状态,以便系统後续进行判断、操作或其他使用,为此我们也在 Day 03 厘清「状态」、「个体」的定义。

范例前情提要

订单:提交 → 待付款 → 待发货→ 待取件→ 交易完成
角色移动模组:站 → 跳 → 站

观点

换个角度观察

  1. 独立的状态
  2. 旧状态 → 新状态,有明确的转移路径

在整理了「主体」、「状态」後发现,希望一个主体的「现阶段的状态」变成「下一个阶段的状态」时,以范例来看,我们没办法单纯透 nextState = f(previusState) ,这个方式来达成。

待付款 → 待发货 中间必须经历过缴费的行为
还没付款不能跳到、转移到等待发货的状态;

站 → 跳 中间必须 按下 B 按键的行为时,才能产生。
匍匐卧倒不能直接转移到跳跃(要先站起来);

1. 那究竟一个状态是如何转移到另外一个状态的呢?

如何让 待付款 → 待发货?

以订单状态为例,系统背後实作可能是,收到一个来自银行的帐单纪录(Call API、 跑 Cron Job 之类的)

如何让 站立 → 跳跃?

以 RPG 为例, 是接收、监听到使用者(玩家)按下键盘 B 的事件。

我们可以把这两个东西称为是种「事件」,我们该如何定义事件呢?

事件是指某些东西,那些东西发生了的话,可能会对系统产生影响、改变...
by Wiki: UML State Machine - Events

而从旧状态 → 新状态,就是种改变,而这种改变是受到了什麽影响?我们称其为「事件」

而在系统中的所有事件,也就是有某些事件会导致我们的状态转移。

状态转移了,必定代表某些事件发生了;但是某些事件发生,不一定会导致状态转移,转移的条件是根据前一个状态以及当下发生的事件所决定。

当站着时,按下 ⇩ (keydown) ,才会卧倒匍匐;
当跳跃时,按下 ⇩ (keydown) ,则不会有反应。

到这里我们似乎有点谱了,既然 nextState = f(previusState) 不成,那 nextState = f(previusState, event) 可以吗?

f('待付款', '收到帐款')  === '待发货'
f('站立', '按 B') === '跳跃'

看起来好像有点搞头了!!

那来思考一下这个 function f 的底层该如何实作呢?我们知道当 旧状态 → 新状态时,要经历了一个事件

什麽事件?特定的事件就像是...
[状态] 是站着时,[事件] 按下 ⇩ (keydown) ,才会卧倒匍匐;
[状态] 是跳跃时,[事件] 按下 ⇩ (keydown) ,则不会有反应。

所以我们必定要有一份表格、纪录,来记录 什麽状态什麽事件,才能进行状态的转换。
当「对的状态」 + 「当对的事件」,才能转换状态,我们称这个行为叫做「转移(Transition)」

所以刚刚的 f 意义上就是那个转移,语意上的命名也就可以叫 transition

transition('待付款', '收到帐款')  === '待发货'
transition('站立', '按 B') === '跳跃'

也因为要做出 Transition 这个 mapping 你必须事先定义出

  1. 所有状态和
  2. 每个状态配上哪些事件能进行转移
  3. 这个转移事件,会将「现阶段的状态」变成哪一个「下一个阶段的状态」

因为要记录这份表格,我们必须事先列下来,也就是代表我们这个主体的状态是有限的。

参考文献


<<:  Day04 安装Django

>>:  [铁人赛 Day04] 如何提升你的 React 网站易用性?(Web Accessibility)(下)- Mouse and pointer events、Development Tools

D16 文件创建页 Create doc

先做了一个简易的文件创建页面 doc_info/views.py 设定成用get载入http://1...

GitHub Actions 基本介绍 - 开始自动化 workflow 的第一步

使用 GitHub Actions 可以让 GitHub Repo 内自订且自动执行你的软件开发流程...

把md档变成Medium文章

订阅patreon即可看到更多文章 https://www.patreon.com/wade3c ...

DAY12 Kotlin基础 函式

欸!?这个不是在 hello world 的时候讲过了ㄇ?! 对。 其实函式还是有其他东西可以讲解的...

[Day 1]-前言

铁人赛来到了第13届,作为资讯人,在这次参赛之前,我也透过铁人赛学习到许多,但直到现在,我才鼓起勇气...