状态模式本质是用多态替代if-else:将状态建模为接口,各具体状态类实现该接口,上下文通过state引用委托调用,jvm运行时动态绑定到实际状态对象的行为,新增状态只需添加类,无需修改现有代码。

Java 利用多态实现状态模式,本质是把“状态”建模为接口或抽象类,再让每个具体状态实现该接口——运行时通过父类型引用调用方法,JVM 自动绑定到实际状态对象的行为。这正是多态(运行时动态绑定)在设计模式中的典型落地。
核心:用多态替代 if-else 状态判断
传统写法中,一个有状态的对象常靠字段(如 int state 或 String status)配合大量条件分支决定行为:
- if (status.equals("RUNNING")) { ... }
- else if (status.equals("PAUSED")) { ... }
- else if (status.equals("STOPPED")) { ... }
这种写法难以扩展、违反开闭原则。而状态模式借助多态,把每个分支逻辑封装进独立类,由 JVM 在运行时自动分发。
关键三步:定义接口 + 实现状态 + 注入上下文
以订单系统为例:
- 定义状态接口:声明所有状态共有的行为,如 pay()、ship()、cancel()
- 实现具体状态类:如 PendingState、PaidState、ShippedState,各自重写接口方法,只写本状态下合法的操作(非法操作可抛异常或静默忽略)
- 上下文持有状态引用:订单类(Order)内部持有一个 State 类型的字段,并提供 setState(State s) 方法;所有业务方法(如 order.pay())都委托给当前 state.pay() 执行
为什么说这是多态在驱动?
看调用过程:
- 上下文里声明的是 private State currentState; —— 编译期只知道它是 State 接口
- 实际赋值可能是 new PaidState() 或 new ShippedState()
- 当执行 currentState.ship() 时,JVM 查看 currentState 指向的真实对象类型,调用对应子类中重写的 ship() 方法
- 无需 if 判断,不改上下文代码,新增状态只需加一个类并更新状态切换逻辑
状态切换也依赖多态机制
状态变更不是简单改字段值,而是替换整个状态对象:
- 比如在 PaidState.pay() 中调用 context.setState(new ShippedState())
- 下一次 context.ship() 就会触发 ShippedState.ship(),因为引用已指向新对象
- 每个状态类可控制自己能转向哪些其他状态,把流转规则内聚在类内部
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











