You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于State模式与Strategy模式的区分疑问及代码验证请求

区分State模式与Strategy模式:你的理解是否正确?

嘿,我来帮你理清这两个容易混淆的设计模式,你的观察其实已经抓住了表象区别,但咱们得从核心意图出发,把这个问题说透~

关于你的第一个疑问

你认为「向上下文传入对象但不保存该对象的是Strategy模式,在上下文中保存状态对象的是State模式」——这个说法是表象上的正确,但没触及核心。保存与否是模式实现的常见特征,但真正区分它们的是设计意图

  • Strategy模式的核心是「算法/策略的动态替换」:上下文需要完成某个明确的任务(比如计算、支付),不同的Strategy是这个任务的不同实现方式。客户端(或上层逻辑)决定用哪个Strategy,上下文通常不会长期持有Strategy(当然也可以持有,但不是必须),重点是「选择不同方法完成同一目标」。
  • State模式的核心是「状态驱动行为变化」:上下文本身有一个内在的状态,这个状态决定了它当前的行为逻辑。上下文会持续持有当前状态,状态的切换(无论是内部触发还是外部触发)会直接改变上下文的行为,甚至状态之间的流转可以由状态对象自身控制(比如状态机逻辑)。

你最初的代码示例太简化了,两个模式的代码几乎一致,因为没体现出各自的核心意图——这也是很多人混淆它们的原因:简单场景下代码结构确实相似,但复杂场景下差异会非常明显。

关于你更新后的代码判断

你的判断完全正确,咱们来拆解一下:

第一组代码(State模式)

interface Istate { void action(); }
class walk : Istate { public void action() { Console.WriteLine("walking !!!"); } }
class run : Istate { public void action() { Console.WriteLine("running !!!"); } }
class fly : Istate { public void action() { Console.WriteLine("flying !!!"); } }
class context { Istate state; public void statePattern() { for (var i = 0; i < 3; i++) { if (i == 0) { state = new walk(); state.action(); } if (i == 1) { state = new run(); state.action(); } if (i == 2) { state = new fly(); state.action(); } } } }
public class client { static void Main() { new context().statePattern(); Console.ReadLine(); } }

这里上下文context持有了state变量,并且在内部切换这个状态来改变自身行为——完全符合State模式的核心:上下文的行为由其当前状态决定,状态是上下文的内在属性。

第二组代码(Strategy模式)

interface Istate { void action(); }
class walk : Istate { public void action() { Console.WriteLine("walking !!!"); } }
class run : Istate { public void action() { Console.WriteLine("running !!!"); } }
class fly : Istate { public void action() { Console.WriteLine("flying !!!"); } }
class context { public void statePattern(Istate state) { state.action(); } public void startegy() { for (var i = 0; i < 3; i++) { if (i == 0) { statePattern(new walk()); } if (i == 1) { statePattern(new run()); } if (i == 2) { statePattern(new fly()); } } } }
public class client { static void Main() { new context().startegy(); Console.ReadLine(); } }

这里上下文context并不持有任何Istate实例,而是每次调用statePattern时传入不同的实例——这本质上是选择不同的策略来执行动作,符合Strategy模式的核心:动态选择不同算法完成任务,策略是外部传入的“工具”,而非上下文的内在状态。

一句话总结

  • 如果你在思考「我应该用哪种方法完成这件事?」——用Strategy模式。
  • 如果你在思考「这个对象现在处于什么状态?它现在应该做什么?」——用State模式。

内容的提问来源于stack exchange,提问作者Lijin Durairaj

火山引擎 最新活动