通用状态机组件通过枚举定义状态与事件契约、泛型上下文委托处理器、规则映射表驱动状态流转,并封装守卫/动作及可复用生命周期钩子,实现解耦、灵活与快速接入。

设计通用状态机组件,核心是把“状态怎么变”和“变了之后做什么”解耦,同时让新业务能快速接入、不改底层。不是写死一堆 if-else,而是用结构换灵活。
定义清晰的状态与事件契约
用枚举统一管理所有合法状态和事件,避免字符串硬编码或魔法值:
- 状态枚举(如 OrderStatus)只包含业务语义明确的取值:CREATED、PAID、SHIPPED、CANCELLED
- 事件枚举(如 OrderEvent)对应外部可触发动作:PAY、SHIP、CANCEL、RECEIVE
- 两者都应加 JavaDoc 注明业务含义和约束,比如 “CANCEL 仅在未发货时允许”
抽象上下文 + 泛型状态处理器
Context 不直接持有具体状态类,而是持有一个泛型状态处理器接口实例,由子类决定如何响应事件:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 定义 StateHandler
接口,含handle(C context, E event)和canHandle(S currentState, E event) - Context 类泛型化(如 StateMachineContext
),内部委托给当前注册的 StateHandler - 状态切换不靠 new 具体类,而由工厂根据 (当前状态, 事件) 查表返回对应处理器
用规则映射替代条件分支
把“什么状态下能响应什么事件”抽成不可变配置,运行时查表驱动:
- 声明 Map
, StateHandler ,键是 (当前状态, 事件) 组合,值是处理逻辑> - 初始化时批量注册,例如:
rules.put(Pair.of(CREATED, PAY), new PayHandler()) - 触发事件时,先查 map;查不到就抛 IllegalTransitionException,明确拒绝非法流转
- 守卫(Guard)和动作(Action)作为独立函数式组件注入到 handler 中,不混在状态类里
封装可复用的生命周期钩子
多数状态机都有共性流程:校验前、执行中、持久化后、通知外系统。把这些抽象为模板方法:
- 在基类 AbstractStateHandler 中定义
preCheck()、execute()、postCommit()、onFailure() - 子类只重写需要定制的部分,比如 PaidHandler 重写
execute()调支付网关,而preCheck()复用父类余额校验 - 所有钩子默认空实现或返回 true,避免强制继承负担
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










