有限状态机FSM(finite-state macine)

常用概念

状态机

状态机(State Machine)全称是[有限状态自动机],不是指一台实际机器,而是现实事物运行规则抽象而成的一个数学模型。它由一组状态转移条件动作组成。

这里的自动可以理解成: 给定一个状态机,同时给定它的当前状态以及输入,那么输出状态是可以明确地运算出来的。

  • 状态, 表示了系统或程序所处的特定情况或阶段, 可以分为改变前状态/改变后状态。
  • 条件, 在什么条件下从一个状态转移到另一个状态。
  • 动作, 状态转移时要执行的操作, 可以理解成一个函数。

有限状态机

通常讨论的状态机都是指有限状态机。实际上讨论的状态机都是有限状态数的。

状态模式

设计模式中的状态模式,

应用场景

有限状态机被广泛应用于计算机科学和电子工程领域,特别是在硬件设计、协议设计、编译器优化等方面有着广泛的应用。

  • 事件驱动编程:状态机可以用于处理事件驱动的编程模型。当系统接收到不同的事件时,状态机可以根据当前状态和事件类型执行相应的操作和状态转换。
  • 业务流程管理:状态机可以用于描述和管理复杂的业务流程。例如,订单处理、审批流程、工作流程等都可以使用状态机来跟踪和控制不同的状态和流转条件。
  • 用户界面:状态机在用户界面开发中非常有用。它可以用于管理用户界面的不同状态和交互流程。例如,表单验证、页面导航、菜单选择等都可以使用状态机来处理用户界面的各种情况。
  • 游戏开发:状态机在游戏开发中广泛应用。游戏中的角色状态、关卡流程、游戏规则等都可以使用状态机来管理和实现。
  • 设备控制:状态机可以用于控制各种设备的行为。例如,自动售货机、自动门、机器人等都可以使用状态机来管理设备的不同状态和行为。
  • 解析器和编译器:状态机在解析器和编译器的实现中非常重要。它可以用于解析和分析源代码,根据语法规则和语义规则执行相应的操作。
  • 网络通信:状态机可以用于描述和管理网络通信协议的状态和行为。例如,TCP连接管理、HTTP请求处理等都可以使用状态机来处理网络通信过程。

实现过程

分支逻辑法:使用if...else/Switch...case实现

适用于条件简单,状态固定,没有新增和扩展的需求。

优点:状态机代码直译,简单直接,状态逻辑比较集中,容易查看。

缺点:对于较复杂的状态机,这种方式容易遗漏或者写错。大量的if-else和switch-case代码分支判断逻辑,可读性和可扩展性比较差,对新增和修改的场景容易引入bug。

查表法:通过二维数组来表达状态机

通过二维数组来表达状态机,适用于复杂状态机,执行动作比较固定和简单的场景,比如游戏这种状态比较多的场景就适合用查表法。

优点:相对于分支逻辑的实现方式,查表法的代码实现更加清晰,可读性和可维护性更好。

缺点:遇到比较复杂的动作,就无法通过简单的二维数组表示了,有一定的局限性。

状态模式:使用状态模式实现

状态模式通过将事件触发的状态转移和动作执行,拆分到不同的状态类中,来避免分支判断逻辑。

优点:代码结构更清晰,可以规避过多的分支逻辑判断,代码可维护性更高。

缺点:状态模式会引入很多状态类,如果状态颗粒度控制不好,会导致状态类爆炸问题;另外逻辑比较分散,集中在状态类中,无法在一个地方整体看出整个状态机的逻辑。

状态机「状态爆炸」问题

传统有限状态机在处理复杂系统时,容易出现「状态爆炸」问题。所谓「状态爆炸」问题,是指在处理过程中,状态的数量呈指数级增长,导致系统的性能急剧下降。为了解决这个问题,可以采用以下几种方法:

  • 子状态划分:将一个大的状态划分为若干个较小的子状态,通过子状态之间的转移来实现大状态之间的转移。这样可以减少系统中的状态数量,降低系统的复杂度。
  • 层次化状态机:将有限状态机分为多个层次,每层包含若干个子状态。通过在不同层次之间进行转移来实现整个系统的状态转移。这样可以减少系统中的状态数量,提高系统的性能。
  • 动态规划:通过对系统的状态进行动态规划,只保留必要的状态信息,从而减少系统中的状态数量。这种方法需要对系统的行为进行分析,以确定哪些状态是必要的,哪些状态是可以省略的。
  • 优化算法:通过对有限状态机的转移函数进行优化,减少不必要的状态转移,从而降低系统的复杂度。这种方法需要对系统的行为进行深入分析,以确定如何优化转移函数。

扩展阅读

此处评论已关闭