从状态机的角度理解程序

657 阅读4分钟

状态机

第一次接触 状态机这个概念,是在 蒋炎岩 的操作系统课程中。 当时还年轻不懂事(其实也就一年前),只是觉得这个名字 is a little bit cool , 似乎有点小高端。

jyy 说了类似于如下的话:

操作系统是一个庞大的计算机程序,而任何一个程序的本质是一个状态机。

我当时并不能理解他说的 所有的程序都是状态机 是什么概念。 虽然我不懂,但我隐隐还是觉得这句话很重要。 可能连我自己都没意识到,这个名词悄悄在我脑子里埋下了种子,在后续的学习中,它一次又一次的发芽生长,甚至有时候作为我理解整个系统的核心因素,

以我现在的理解重新品味这句话: 所谓的状态是指程序中的承载数据的容器,或者你可以把他理解成一个个变量。 如果把程序看作一个生物,那么 状态(数据)好比是他的细胞,一堆一堆细胞组成了组织,组织最终相互配合形成了系统, 而状态机就是说,程序建立在这些 细胞,组织,器官,系统上。

现在回过头来看这句话,它似乎揭示了这样一个现象:

任何一个程序,所有的操作都是对数据的读和写。

这句话看起来蛮废话的。因为他的视角太过微观了。就好像我们用显微镜盯着一个细胞在看这是个什么生物。 但咱们不妨把显微镜换成普通的眼镜,将视角从微观转到宏观,他说明了什么问题呢?

我们观察任何一个系统,可以尝试从数据的流动作为线索。

下图是我对数据流动的一个 抽象描述: image.png

系统外部:

  • 输入
  • 输出

    系统外部是用户对软件的交互,以前端为例,用户的输入,点击...等操作可以视为信息的输入,我们对 UI 的渲染可以视为 输出。

系统内部:

  • 状态
  • 对状态的操作(状态的消费)

上述图实际上有以下一些特点:

  1. 将数据与对数据的操作解耦。
  2. 在操作数据时,可能会产生一些中间态的数据,要注意这些中间态数据的安全性,尽量不要暴露。

数据结构与消费

说了那么多有的没的,接下来说点我想特别强调的。也是真正对大家可能有帮助的内容:

观察一个系统时,尝试用以下视角进行观察和思考:

  • 这个系统依赖的数据结构是怎样的
  • 消费数据的过程是怎样的(数据流动过程)

可能看到这两句话有点云里雾里,我来解释下: 我以前看待程序的时候,尤其是读别人的源码,没有重点,不知道怎么划分重点。

但我如今看待别人的代码时,我会想:

  1. 实现某个功能需要依赖哪些数据?这些数据是如何组织的?
  2. 通过怎样的流动拿到依赖的数据?
  3. 如何消费这个数据的?(这一步就是具体的操作了)

这里的核心是宏观上的抽象: 将一个完整的程序抽象成两大块内容:

  • 数据
  • 消费数据的方法

    有些函数是用来生成待消费的数据,有些函数可能只是作为中转站运载了一下数据,有些函数是根据数据的值做一些具体的处理然后得到处理后的数据。我们可以根据这些特征对函数进行分类,以更好的掌握全局。

另外可以在某个过程先暂时屏蔽数据转换的细节,只去思考状态的迁移

  • 数据起初是怎样的(生的)
  • 数据经过流动后需要变成怎样(熟的)

    这种只关注数据结果,而不关注数据具体如何转换的思路可以帮助我们更宏观的掌握系统

再用数据流动 把 数据的消费 过程串联起来

总结

最近在学习 React 源码以及其周边的源码,我越来越发现宏观上的抽象有多么重要,一个正确的抽象可以帮助我们理解复杂的系统。倘若关注一个个函数如何调用,很快你就会昏掉,因为函数太多了,而且逻辑上没有强关联。

但是倘若我们开始思考: 这个函数是在干嘛?生产数据?中转数据?消费数据? 我们就能理解这个复杂的系统。

或者我们也可以把系统抽象成 数据的生产,消费,输出的过程。

总而言之,抽象是学习理解一个庞大系统的神兵利刃,抽象也是为我们今后的创造做一些基础。

--end