面试知识库
进阶

状态模式#

一句话答案#

将状态相关行为封装到状态类中,状态切换时切换状态对象,消除复杂 if-else,适合订单状态/审批流程。

核心要点

状态模式允许对象在内部状态改变时改变行为,看起来好像修改了它的类。不同状态被封装为独立的类,行为委托给当前状态对象。

核心区别:

维度状态模式策略模式
切换方式状态在内部自动转换(对客户透明)策略由客户端外部指定
关注点对象行为随状态变化而变化同一行为有不同的算法实现
状态间关系各状态之间有转换关系(状态机)各策略之间独立,无关联
客户端感知客户端不知道有几种状态客户端主动选择策略
典型场景订单状态机、TCP 连接状态、审批流程不同排序算法、不同支付方式

状态模式示例——订单状态机:

一句话区分: 状态模式中,状态的切换是内部驱动的(对客户透明);策略模式中,策略的选择是外部指定的(由客户端决定)。

面试回答(2分钟版)

状态模式的核心是把不同状态下的行为封装到各自的状态类中,当对象的状态发生变化时切换到对应的状态对象,从而消除大量的 if-else 或 switch-case。比如订单系统中,订单有待支付、已支付、已发货、已完成等状态,每个状态下支付、发货、确认收货这些操作的行为完全不同。用状态模式的话,每个状态是一个独立的类,实现统一的状态接口,状态转换逻辑封装在各状态类内部。和策略模式最关键的区别在于:状态模式的切换是内部自动驱动的,客户端不需要知道有哪些状态,比如调用 pay() 后状态自动从待支付变为已支付;而策略模式是由客户端主动选择用哪个策略。状态之间有明确的转换关系形成状态机,策略之间则是独立平行的。实际项目中订单状态机、审批流程、TCP 连接状态管理都适合用状态模式。Spring 也提供了 Spring State Machine 框架来支持更复杂的状态机场景。

追问与易错

追问方向:

  • “和策略模式区别?”→ 状态模式的切换由对象内部自动驱动(客户端不感知状态种类),状态之间有转换关系形成状态机;策略模式由客户端主动选择,各策略独立无关联
  • “订单状态机怎么用状态模式?”→ 每个订单状态(待支付/已支付/已发货/已完成)封装为独立的状态类,实现统一接口(pay/ship/confirm),状态转换逻辑在各状态类内部完成,OrderContext 持有当前状态对象并委托调用
  • “Spring State Machine 了解吗?”→ Spring 提供的状态机框架,通过配置定义状态、事件和转换规则,支持守卫条件、动作回调、持久化等,适合复杂状态机场景(如多级审批流程),比手写状态模式更规范

易错点:

  • ❌ 状态模式就是 if-else 替代——核心是状态转换封装
  • ❌ 混淆状态和策略——状态随时间变化策略由客户端选