Statecharts 很老。David Harel 在 1987 年就把它称为“A visual formalism for complex systems”,复杂系统的视觉形式化。
反常点在这里:到今天,statecharts.dev 还要用一整组教程页解释它是什么、解决什么、为什么没被广泛使用。
这不是某个新产品发布,也不是库作者又造了一个概念。它更像一次补课:软件团队已经被复杂交互折磨很久,但很多状态仍然藏在代码缝里。
Statecharts 解决的是状态爆炸,不是画图审美
Statecharts 可以理解为增强版状态机。
普通状态机在简单场景里很好用。按钮开关、表单提交、弹窗显示,几种状态就够了。但交互一复杂,就会遇到 state explosion:状态组合越来越多,分支越来越碎,最后图和代码一起膨胀。
Statecharts 加了层级、并行、历史状态等机制。目的不是让图更漂亮,而是把行为关系摊开。
| 问题 | 普通写法里的表现 | Statecharts 的处理方式 | 对团队的影响 |
|---|---|---|---|
| 状态爆炸 | loading、error、retry、disabled 到处组合 | 用层级和并行拆复杂度 | 少一点组合地狱 |
| 隐含状态 | if、flag、callback 分散在组件里 | 把状态和转移显式化 | 异常路径更容易暴露 |
| 行为耦合 | UI 组件顺手塞业务流程 | 行为模型与组件解耦 | UI 改版不必重写流程 |
| 测试困难 | 只测主路径,边角靠人记 | 模型可独立测试 | QA 更容易参与讨论 |
| 沟通成本 | 产品、开发、测试各说各话 | 图成为共同语言 | 非开发者也能看懂大方向 |
最关键的一点很朴素:你本来就在写状态机。
只是很多团队没有承认这件事。它们把状态机拆成几个变量、几个回调、几个临时判断。短期很快,长期很贵。
“天下大事,必作于细。”放到软件里,就是复杂行为最后都要落到状态和转移上。你不画出来,它也会存在。只是换成线上事故提醒你。
好处很硬,代价也别装看不见
Statecharts 的核心收益有三类。
行为从组件里抽出来,组件不再承担太多流程责任。模型可以单独测试,异常路径更容易被枚举。图也能让产品、QA、开发在同一张行为地图上讨论。
可执行 Statecharts 又往前走一步。模型既是图,也是运行时行为的单一事实源。这样可以减少“图是一套、代码是一套”的脱节。
但它不是免费午餐。
团队要学新范式。小场景可能增加代码量。可执行 Statecharts 的工具、格式、类型安全也仍有局限。图复杂之后,本身也会变成维护负担。
SCXML 值得放在这里看。W3C 从 2005 到 2015 推过 Statechart XML 标准化。它说明 Statecharts 有工程标准史,不是某个库的个人偏好。
但标准不等于普及。XML 时代留下过很多标准,也留下过很多没有变成日常工作流的标准。Statecharts 的难点也在这里:它不是“会不会画图”,而是“团队愿不愿意按模型工作”。
对前端和交互复杂系统开发者,动作可以很具体:
| 场景 | 建议 |
|---|---|
| 简单表单、普通开关、一次性页面 | 不必硬上 Statecharts,普通代码更直接 |
| 多步骤流程、支付、权限流转、重试、取消、异常补偿 | 先画状态与转移,再决定是否引入可执行工具 |
| 已经有大量 flag 和分支互相打架 | 先从最痛的一个流程迁移,不要全站重构 |
| QA 经常补问“这个状态下还能不能点” | 把行为模型拿出来共同评审 |
对技术负责人和架构师,重点不是采购一个工具,而是改评审方式。
复杂流程的设计评审,不能只看页面稿和接口文档。要看状态有哪些,事件有哪些,取消和失败怎么走,恢复到哪里。否则代码评审只是给隐含状态盖章。
我不买账的是“可视化所以简单”
Statecharts 没被广泛使用,原因不难理解。
很多人不知道它。知道的人也会说 YAGNI:现在还用不上,别过度设计。这个判断在小系统里成立。一个简单按钮硬上 Statecharts,确实不划算。
问题在复杂系统里。
前端应用、支付流程、协作编辑、设备控制、AI Agent 工作流,都会遇到并行、取消、重试、超时、补偿、权限变化。每多一个变量,隐含状态就多一层。最后没人能完整说清系统会怎么动。
我不太买账的是把 Statecharts 包装成“可视化所以简单”。可视化只是把复杂性搬到台面上,不会自动消灭复杂性。
真正的分水岭是工作流。
团队愿不愿意在写代码前先承认行为模型?愿不愿意让 QA 参与状态评审?愿不愿意为异常路径付出设计成本?愿不愿意接受小场景代码量可能变多?
这才是 Statecharts 反直觉的地方。它不是让你更快写第一版,而是让你少在第十版时崩掉。
接下来最该看三件事。
| 观察点 | 为什么重要 |
|---|---|
| 工具链能否更好接入 TypeScript 和主流前端框架 | 类型安全和开发体验决定日常可用性 |
| 团队是否把图用于测试和评审,而不只是文档 | 只当文档,迟早和代码分叉 |
| 是否只在高复杂流程落地 | 全量推广容易变成形式主义 |
小系统别神化它,大系统别逃避它。
图可以不用,模型意识不能没有。复杂交互最怕的不是代码长,而是没人说得清它到底会怎么动。
