← 返回题目列表

状态模式和策略模式有什么区别?

高频 中等 第 5 / 25 题 更新于 2026/07/28
状态模式策略模式设计模式对比行为型模式

简化版

状态模式和策略模式结构很像,都是把行为委托给一个接口实现类。区别在于:策略模式是客户端主动选择一种算法,通常策略之间彼此独立;状态模式是对象内部状态变化导致行为变化,状态之间往往存在迁移关系。

详细版

两者的相似点是都使用组合和多态,把变化的行为封装到独立类中。

区别主要有三点:

  1. 意图不同:策略模式解决算法可替换,状态模式解决状态驱动行为变化;
  2. 控制方不同:策略通常由客户端或配置选择,状态通常由 Context 内部状态迁移决定;
  3. 关系不同:策略之间一般相互独立,状态之间通常有合法迁移关系。

比如支付方式选择微信、支付宝、银行卡,这是策略模式;订单从待支付到已支付、已发货、已完成,这是状态模式。

面试时可以说:如果关注“选哪个算法”,更像策略;如果关注“当前状态决定能做什么,以及下一步迁移到哪里”,更像状态模式。

完整版教学

一、为什么两者容易混淆

策略模式和状态模式代码结构非常像:

context.setXxx(interfaceImpl);
context.operation();

它们都把行为封装成接口实现类,都依赖多态执行不同逻辑。

所以只看类图,很难区分。真正要看的是设计意图。

二、策略模式关注“算法选择”

策略模式里,多个策略通常是平级替换关系。

比如折扣计算:

满减策略
折扣策略
会员价策略
新人券策略

一次计算选择其中一种或几种策略。策略之间通常不会说“满减策略执行完后自动切换成折扣策略”。

策略模式重点是让算法可替换。

三、状态模式关注“状态驱动行为”

状态模式中,状态不是随便选的,而是对象生命周期的一部分。

比如订单状态:

待支付 -> 已支付 -> 已发货 -> 已完成
待支付 -> 已取消
已支付 -> 已退款

每个状态能执行哪些操作,执行后迁移到哪个状态,都有业务规则。

状态模式重点是让对象在不同状态下表现出不同行为。

四、控制权不同

策略模式通常由外部决定用哪个策略:

calculator.setStrategy(new VipDiscountStrategy());

状态模式通常由对象内部状态推进:

order.pay(); // 内部从 WaitPayState 迁移到 PaidState

客户端不应该随意把订单从“待支付”直接改成“已完成”。状态迁移要受业务规则约束。

五、策略之间独立,状态之间有关联

策略模式中的策略一般彼此独立。

今天用 A 策略,明天用 B 策略,不代表 A 和 B 之间有生命周期关系。

状态模式中的状态通常有关联:

  • 哪些状态可以迁移;
  • 哪些迁移非法;
  • 迁移时要做什么动作;
  • 迁移失败如何回滚。

这就是状态模式比策略模式更强调“状态图”的原因。

六、它们可以组合使用

真实项目中状态模式和策略模式可以同时出现。

比如订单处于“已支付”状态时,要计算发货策略:

  • 普通仓发货;
  • 前置仓发货;
  • 跨境仓发货。

订单状态决定当前能不能发货,这是状态模式;发货算法如何选择,这是策略模式。

七、外部选择算法与内部生命周期迁移

200 元订单可任选八折或满减两个策略;同一订单从 Pending→Paid→Shipped 则是有方向的 3 个状态。

strategy: selector -> algorithm; state: current --event--> next

状态题的正确性落在“当前状态 + 事件 + 守卫条件 → 目标状态”这一条边上,而不是类数量上。每条边都要说明持久化原子性、重复事件结果和副作用触发时机,非法边则必须得到稳定且可观测的拒绝。

八、迁移一致性、幂等与并发验证

检查维度应确认的内容
机制正确性一个状态内部仍可选择支付或运费策略,两种模式能够组合。
适用边界策略通常彼此独立并由外部选择,状态之间有合法边并由事件推动;二者代码结构相似但意图不同。
测试证据用状态×事件矩阵覆盖全部合法边与非法边,并验证两类结果都符合统一错误契约
工程代价重点评估状态数、迁移边数、一次迁移的数据库竞争,以及新增状态对完整迁移矩阵的影响

易错点:一个状态内部仍可选择支付或运费策略,两种模式能够组合。

九、常见误区与追问

  • 误区:状态模式只是自动选择策略。 状态承载生命周期语义和迁移约束,不只是选择来源不同。
  • 误区:把状态码换成状态类就自动消除了所有条件判断。 状态对象只能封装状态相关行为;持久化、并发控制、权限和跨聚合规则仍需显式设计。
  • 追问:怎样从需求语言快速判断? 出现“选择哪种算法”偏策略,出现“当前阶段允许什么、下一步到哪”偏状态。
  • 追问:非法状态迁移应该静默忽略吗? 不应该;应返回明确业务错误并记录当前状态、事件和聚合标识,重复事件则按幂等规则单独处理。
  • 追问:状态模式最容易漏掉哪类测试? 非法迁移、重复事件和并发竞争;它们比单线程成功路径更能证明状态模型可靠。

十、加强记忆

状态模式和策略模式都用多态封装行为,但关注点不同。策略模式问“这次选哪个算法”,状态模式问“当前状态下能做什么,做完迁移到哪里”。策略通常外部选择、彼此独立;状态通常内部推进、存在生命周期和合法迁移关系。