java状态模式的核心是将状态抽象为对象,通过统一接口定义行为、具体类实现状态逻辑、上下文委托执行并管理状态流转,从而解耦条件判断、提升可维护性与扩展性。

在面向对象系统中,Java 使用状态模式管理状态的核心思路是:把“状态”本身变成对象,让每个状态独立封装自己的行为,再由上下文(Context)持有并委托给当前状态对象执行操作。这样就避免了在业务类里堆砌大量 if-else 或 switch 判断,使状态逻辑清晰、可插拔、易扩展。
明确状态边界,定义统一状态接口
先识别业务中有哪些互斥且行为差异明显的状态(比如订单的「待支付」「已支付」「已发货」「已完成」「已取消」)。然后定义一个抽象状态接口,声明所有状态共有的行为方法:
- 方法名应体现业务语义,如
pay()、ship()、cancel() - 接口不实现逻辑,只约定契约;每个具体状态类必须提供自己的实现
- 避免在接口中暴露状态转换细节(如
toNextState()),保持职责单一
为每个状态编写具体实现类
每个具体状态类实现状态接口,并只负责本状态下的合法行为和转换规则:
- 例如
PaidState中,ship()可以执行发货逻辑并切换到ShippedState;而cancel()可能抛异常或返回失败,因为已支付订单通常不允许直接取消 - 状态类之间不直接依赖,也不互相创建——它们只通过上下文间接协作
- 若状态转换逻辑较复杂(如需校验、触发事件、更新数据库),可在状态类内部调用上下文提供的服务方法,而非自行处理数据持久化
设计上下文类,集中管理状态生命周期
上下文类是业务主体(如 Order 或 RaffleActivity),它持有一个 State 类型的引用:
- 构造时初始化默认状态(如新建订单默认为
CreatedState) - 对外暴露业务方法(如
order.pay()),内部直接委托给当前状态对象执行 - 提供
setState(State newState)方法,由具体状态类在适当时机调用(比如支付成功后,PendingPaymentState主动设为PaidState) - 可选:在
setState中加入日志、事件通知或状态合法性校验(防止非法跳转,如从「已完成」回到「待支付」)
注意状态流转的可控性与一致性
状态不是随意切换的,必须反映真实业务约束:
- 避免让客户端代码直接 new 状态对象并调用
context.setState(...)——应由当前状态决定何时、切换到哪个下一状态 - 如果状态路径固定(如 A→B→C→D),可在状态类中硬编码跳转;若路径动态(如审批流),可引入状态配置或规则引擎辅助决策
- 考虑线程安全:若上下文被多线程共享,状态变更需同步(如用
synchronized或原子引用),否则可能引发状态错乱
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











