关于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




