Java中用分支控制流实现简单状态机,核心是用enum定义状态与事件,以switch按当前状态分支处理合法事件,显式更新状态并附加业务动作,再封装为可复用类,加入空事件校验、终态保护和日志埋点等防护措施。

明确状态与事件的边界
状态是系统在某一时刻的快照,比如 `INITIAL`、`USERNAME_INPUT`、`LOGIN_SUCCESS`;事件是外部触发动作,比如 `INPUT_USERNAME`、`LOGIN_ATTEMPT`。两者都建议用 `enum` 定义,保证类型安全、可读性强、避免字符串硬编码出错。示例:
public enum LoginState { INITIAL, USERNAME_INPUT, PASSWORD_INPUT, LOGIN_SUCCESS, LOGIN_FAILURE }
public enum LoginEvent { INPUT_USERNAME, INPUT_PASSWORD, LOGIN_ATTEMPT, INVALID_CREDENTIALS }
用 switch 驱动状态流转
以当前状态为分支依据,每个 `case` 内只处理该状态下合法的事件。遇到非法事件或未覆盖情况,可抛异常或打印警告,避免静默失败。关键点:
- 每个 `case` 后必须加 `break`,防止穿透
- 状态更新要显式赋值,比如 currentState = LoginState.USERNAME_INPUT
- 可在每个分支中附加业务动作,如打印提示、校验参数、调用服务
片段示例:
switch (currentState) {
case INITIAL:
if (event == LoginEvent.INPUT_USERNAME) {
currentState = LoginState.USERNAME_INPUT;
System.out.println("等待输入用户名");
}
break;
case USERNAME_INPUT:
if (event == LoginEvent.INPUT_PASSWORD) {
currentState = LoginState.PASSWORD_INPUT;
System.out.println("等待输入密码");
}
break;
// 其他 case …
}
封装成可复用的状态机类
把状态变量、事件处理器、获取当前状态的方法打包进一个类,对外只暴露 `handleEvent()` 和 `getCurrentState()`。这样调用方无需关心内部判断细节,也便于后期替换为更高级实现(如表驱动、Spring State Machine)。结构示意:
立即学习“Java免费学习笔记(深入)”;
- 私有字段:private LoginState currentState;
- 构造器初始化为初始状态
- 公开方法:public void handleEvent(LoginEvent event)
- 辅助方法:public LoginState getCurrentState()
加入基础防护与可测试性
真实项目中需考虑:- 空事件校验:传入 `null` 时提前 throw IllegalArgumentException
- 终态保护:如 `LOGIN_SUCCESS` 后不再响应任何事件,直接返回或忽略
- 日志/监控埋点:在状态变更前后记录 traceId 或打点,方便排查流程卡点
- 单元测试覆盖:每个状态 + 每个合法事件组合都应有对应 test case


















