状态模式通过将状态行为封装到独立类中,利用多态实现运行时动态切换,消除if-else判断;上下文仅委托调用,状态转换由状态对象自主驱动,新增状态无需修改现有代码。

状态模式通过将不同状态下的行为封装到独立的类中,利用多态让对象在运行时动态切换具体行为,从而避免大段 if-else 或 switch 判断。
把状态逻辑拆成独立类
每个状态对应一个实现统一接口(如 State)的类,比如 IdleState、RunningState、PausedState。它们各自实现相同方法(如 handle()),但内部逻辑完全不同。对象持有一个 State 类型的引用,调用时无需判断当前是什么状态,直接委托给当前状态对象处理。
上下文类只负责委托,不写条件判断
上下文类(如 Player)不再包含状态判断逻辑。它只保存当前状态引用,并在需要响应事件时调用 currentState.handle()。状态切换也由状态对象自己决定——比如 RunningState.handle() 执行完后,可主动把上下文的 currentState 改为 PausedState 实例。
- 上下文不关心“现在是哪种状态”,只关心“当前状态怎么处理”
- 新增状态只需新增一个类,不修改上下文和其他状态类
- 状态间转移规则被封装在各个状态内部,职责清晰
状态转换由状态对象自己驱动
状态之间的流转不是靠外部用 if 控制,而是由当前状态决定下一步该变成什么。例如:RunningState 的 handle() 方法里检测到暂停指令,就调用 context.changeState(new PausedState());PausedState 收到继续指令,就调用 context.changeState(new RunningState())。
这样,控制流自然地从一个状态对象流向另一个,条件分支彻底消失。
接口定义要聚焦行为,而非状态标识
定义 State 接口时,方法名应体现“能做什么”,比如 pressStart()、pressPause()、pressStop(),而不是 getStateName() 或 isRunning()。这样调用方不需要先判断状态再决定调用哪个方法——所有操作都通过多态分发,编译器和 JVM 自动选对实现。
- 避免暴露状态枚举或字符串,防止外部用
if (state == RUNNING)再分支 - 每个状态类只实现它“能响应”的操作,不响应的操作可抛异常或空实现
- 接口方法设计贴近业务动作,而非技术状态值
不复杂但容易忽略:关键不在“用了接口”,而在“谁来决定下一步状态”。只要转移逻辑从条件语句移到状态对象内部,多态就真正开始消除分支。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











