状态机(State Machine)详解
本质概念
状态机是一种数学建模工具,用于描述系统在不同状态之间的转移过程。它的核心思想是:系统在任何给定时刻只处于有限状态中的某一种状态,外部输入(事件)会触发状态转移,并可能伴随动作的执行。
graph LR
A[状态A] -->|事件X/动作1| B[状态B]
B -->|事件Y/动作2| C[状态C]
C -->|事件Z/动作3| A
三大核心组件
-
状态(States):
- 系统可能存在的有限个稳定状况
- 分为初始状态、中间状态、终止状态
- 例如:红绿灯的
红灯、绿灯、黄灯
-
转移(Transitions):
- 状态之间转换的规则
- 由事件(输入)触发
- 可附带动作(输出)
- 例如:绿灯状态下
收到计时信号→黄灯,同时启动倒计时
-
事件(Events):
- 触发状态转移的外部输入
- 例如:用户操作、系统消息、时间信号
状态机类型对比
| 类型 | 名称 | 特点 | 应用场景 |
|---|---|---|---|
| 米利型 | Mealy Machine | 转移依赖当前状态和输入 | 大多数实际应用 |
| 摩尔型 | Moore Machine | 转移仅依赖当前状态 | 简单控制逻辑 |
| 层次型 | Hierarchical State Machine | 状态可嵌套子状态机 | 复杂UI系统 |
| 并行型 | Parallel State Machine | 多个状态机并发运行 | 多任务处理系统 |
代码实现:自动售货机状态机
from enum import Enum, auto
# 定义状态
class VendingState(Enum):
IDLE = auto() # 空闲状态
SELECTING = auto() # 选择商品
PAYING = auto() # 支付中
DISPENSING = auto() # 出货中
# 实现售货机状态机
class VendingMachine:
def __init__(self):
self.state = VendingState.IDLE
self.selected_item = None
# 事件处理
def select_item(self, item):
if self.state == VendingState.IDLE:
print(f"已选择商品: {item}")
self.selected_item = item
self.state = VendingState.SELECTING
else:
print("当前不能选择商品")
def insert_money(self, amount):
if self.state == VendingState.SELECTING:
if amount >= 10: # 假设商品10元
print("付款成功")
self.state = VendingState.PAYING
self.dispense()
else:
print("金额不足")
else:
print("未选择商品")
def dispense(self):
if self.state == VendingState.PAYING:
print(f"正在出货: {self.selected_item}")
self.state = VendingState.DISPENSING
self.complete()
def complete(self):
print("交易完成,谢谢惠顾")
self.state = VendingState.IDLE
self.selected_item = None
# 测试售货机工作流程
vm = VendingMachine()
vm.select_item("可乐")
vm.insert_money(10)
应用场景
-
UI系统:

-
游戏开发:

-
通信协议(TCP状态机):

高级扩展概念
-
层级状态机:
class ComplexState: def __init__(self): self.main_state = MainState.STATE_A self.sub_state = SubState.SUBSTATE_1 def handle_event(self, event): # 先处理子状态 if self.sub_state == SubState.SUBSTATE_1: # 子状态处理逻辑... pass # 父状态处理 elif self.main_state == MainState.STATE_A: # 父状态逻辑... pass -
状态图工具:
- PlantUML:基于文本的状态图生成
- Statecharts:复杂状态机建模标准
- XState:JavaScript状态机库
-
时序逻辑检查:
- 使用LTL(线性时序逻辑)验证状态转移
◻(绿灯 → ◊(黄灯)) # 绿灯最终必定变为黄灯 ¬◊(绿灯 ∧ 红灯) # 绿灯和红灯不可能同时存在
设计原则
-
有限状态原则:
- 系统状态必须是有限且明确的
-
单激活原则:
- 任一时刻只有一个活动状态(并行状态机除外)
-
明确转移原则:
- 每个转移必须有明确的触发条件
-
动作隔离原则:
- 状态转移过程中的动作不应改变其他状态
优化技巧
-
状态模式实现:
class State(ABC): @abstractmethod def handle(self, context): pass class ConcreteStateA(State): def handle(self, context): context.state = ConcreteStateB() class Context: def __init__(self): self.state = ConcreteStateA() def request(self): self.state.handle(self) -
状态表驱动法:
transitions = { (VendingState.IDLE, 'SELECT'): ('SELECTING', select_action), (VendingState.SELECTING, 'PAY'): ('PAYING', payment_action), (VendingState.PAYING, 'DISPENSE'): ('DISPENSING', dispense_action) } def handle_event(event): current_state = machine.state key = (current_state, event) if key in transitions: new_state, action = transitions[key] action() machine.state = new_state -
可视化调试:
def trace_state_change(old, new, event): print(f"State: {old.name} → {new.name} [Event: {event}]") logger.debug(f"Transition at {datetime.now()}")
状态机通过将复杂流程分解为离散的状态和转移关系,显著提高了系统的可预测性和可维护性,是解决复杂逻辑控制的利器。

详解&spm=1001.2101.3001.5002&articleId=148652321&d=1&t=3&u=28ebad787d1d4dd2be33b03b5fe69931)
2881

被折叠的 条评论
为什么被折叠?



