状态模式通过将状态逻辑封装到独立类中,使对象行为随状态变化而变化,避免条件判断;核心角色为context(持有状态引用并委托行为)、state(定义统一接口)和concretestate(实现具体状态逻辑并控制转换);状态转换通常由具体状态类自主触发,以符合单一职责;可通过内部校验或状态转移表确保流转安全;状态对象需访问context,建议弱引用或参数传入以防循环依赖。

状态模式通过将状态逻辑封装到独立类中,让对象在不同状态下表现出不同行为,避免大量条件判断,使状态转换更清晰、易维护。
核心结构:上下文 + 状态接口 + 具体状态
状态模式有三个关键角色:
- Context(上下文):持有当前状态引用,提供统一接口供外部调用;所有行为委托给当前状态对象执行。
- State(状态接口/抽象类):定义所有状态共有的行为方法(如 handle()、transitionTo()),具体实现由子类完成。
- ConcreteState(具体状态):每个子类实现一种状态下的逻辑,并可决定是否触发状态转换(比如调用 context.setState(new NextState()))。
状态转换的主动权在谁手里?
通常由具体状态类控制转换时机和目标,而非 Context 主动判断。这样把“什么条件下变成什么状态”的逻辑下放到对应状态内部,更符合单一职责。
例如订单状态中:“待支付”状态收到支付成功事件时,自己决定切换为“已支付”;而“已支付”状态在发货后才转为“已发货”。这些规则藏在各 ConcreteState 的方法里,Context 只负责转发请求和更新 state 引用。
如何安全地管理状态流转?
避免非法跳转(如从“已完成”退回“待支付”),推荐两种方式:
- 在 ConcreteState 内部校验:handle() 方法开头检查当前操作是否允许,不合法则抛异常或忽略。
-
用状态转移表约束:Context 初始化时配置 Map
>,表示每个状态能合法转向哪些状态;setState() 前做校验。
后者更集中、易配置,适合状态多且流转规则复杂的情况。
要不要让状态对象持有 Context 引用?
需要,但建议弱引用或通过方法参数传入,避免循环依赖和内存泄漏。
- 具体状态常需调用 Context 的方法(如 setState、获取业务数据),所以通常构造时传入 Context 或通过回调传参。
- 若 State 是无状态的(如枚举单例),可用静态工厂 + Context 参数化行为,减少对象创建开销。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











