战略设计模式和国家设计模式之间的区别是什么?我在网上浏览了不少文章,但看不出明显的区别。
有人能用外行的语言解释一下吗?
战略设计模式和国家设计模式之间的区别是什么?我在网上浏览了不少文章,但看不出明显的区别。
有人能用外行的语言解释一下吗?
当前回答
在我看来,主要的区别在于他们的意图。从技术上讲,国家和战略模式看起来非常相似。 主要区别在于:
State模式在需要时更改上下文的状态,并且状态可以多次更改。context改变它的状态或者状态可以设置另一个状态 战略模式决定战略,战略很少会改变,而环境不会改变战略。
策略模式。
我们抽象出一些合理的策略:
public interface ISound
{
void Make();
}
及其具体策略:
public class DogSoundStrategy : ISound
{
public void Make()
{
Console.WriteLine("Bar");
}
}
public class CatSoundStrategy : ISound
{
public void Make()
{
Console.WriteLine("Meow");
}
}
这是对能发声的Animal的抽象描述:
public abstract class Animal
{
public void MakeSound(ISound sound)
{
sound.Make();
}
}
具体的动物是这样的:
public class Dog : Animal
{
}
public class Cat : Animal
{
}
然后我们可以像这样调用上面的代码:
Dog dog = new Dog();
dog.MakeSound(new DogSoundStrategy()); // there is a small chance
// that you want to change your strategy
Cat cat = new Cat();
cat.MakeSound(new CatSoundStrategy()); // there is a small chance
// that you want to change your strategy
有一个小的机会,你想要改变你的策略。
状态模式
想象一下,你有一个电脑游戏,英雄可以是世界上任何一个超级人物。让我们称他为英雄。他能跑、能游、能飞,还能变成钢铁侠或蜘蛛侠。你有一个按钮,你可以改变它的形状或状态为钢铁侠或蜘蛛侠。
英雄的代码是这样的:
public class Hero
{
IState _state;
public Hero()
{
_state = new SpiderManState();
}
public void Run()
{
_state.Run();
}
public void Swim()
{
_state.Swim();
}
public void Fly()
{
_state.Fly();
}
public void ChangeShape()
{
_state = _state.SetShape();
}
}
IState的接口看起来像这样:
public interface IState
{
void Run();
void Swim();
void Fly();
IState SetShape();
}
具体的状态是这样的:
public class SpiderManState : IState
{
public void Fly()
{
Console.WriteLine("Spiderman is flying");
}
public void Run()
{
Console.WriteLine("Spiderman is running");
}
public void Swim()
{
Console.WriteLine("Spiderman is swimming");
}
public IState SetShape()
{
return new IronManState();
}
}
IronManState会是这样的:
public class IronManState : IState
{
public void Fly()
{
Console.WriteLine("IronMan is flying");
}
public void Run()
{
Console.WriteLine("IronMan is running");
}
public void Swim()
{
Console.WriteLine("IronMan is swimming");
}
public IState SetShape()
{
return new SpiderManState();
}
}
现在通过点击英雄类的ChangeShape()按钮,你将能够改变英雄的状态, 例:从蜘蛛侠到钢铁侠。
因此,上下文状态(英雄)取决于并可以通过其按钮ChangeShape进行更改。这种情况会发生很多次。
您很有可能希望更改上下文的状态。
状态模式也可以被认为是替代类中许多if - else语句的一种选择。
其他回答
In Strategy pattern while implementing searching , we can have multiple strategies of searching e.g NaiveStrategy(), KMPStrategy() or RabinKarp() Strategy. These are all independent and there are somewhat stable choices. And most important, strategies can't shift from one another. Only Context is able to change strategies. State Pattern on the other hand is based on concept of Finite-State Machines. The states can transition from one another. Here states are less stable as compared to the strategies. And one thing, each concrete state maintains a reference to context and hence is able to transition to another state.
因此,关键在于在策略中,只有上下文可以设置策略,而在状态模式下,状态可以转换到其他状态。在策略模式中,策略彼此不知道。而在状态模式中,状态并不是不知道彼此,并且在它们维护对上下文对象的引用时允许转换。
“策略使这些对象完全独立,彼此不知道。然而,State不限制具体状态之间的依赖关系,允许它们随意改变上下文的状态。”
参考资料:https://refactoring.guru/design-patterns/strategy
不同之处在于它们解决的问题不同:
State模式处理对象(处于)什么(状态或类型)——它封装了依赖状态的行为,而 策略模式处理对象如何执行特定任务——它封装了一个算法。
然而,实现这些不同目标的结构非常相似;这两种模式都是带有委托的组合示例。
关于它们的优点:
通过使用State模式,状态保持(上下文)类不再知道它是什么状态或类型以及可用的状态或类型。这意味着类遵循开闭设计原则(OCP):类对状态/类型的更改是关闭的,但是状态/类型对扩展是开放的。
By using the Strategy pattern the algorithm-using (context) class is relieved from knowledge of how to perform a certain task (-- the "algorithm"). This case also creates an adherence to the OCP; the class is closed for changes regarding how to perform this task, but the design is very open to additions of other algorithms for solving this task. This likely also improves the context class' adherence to the single responsibility principle (SRP). Further the algorithm becomes easily available for reuse by other classes.
考虑一个处理客户呼叫的IVR(交互式语音应答)系统。你可能想要编程它来处理客户:
工作日 假期
要处理这种情况,您可以使用状态模式。
节假日:IVR简单地回复说“只能在工作日上午9点到下午5点之间接听电话”。 工作日:它通过将客户连接到客户服务主管来响应。
这个连接客户和支持高管的过程本身可以使用一个策略模式来实现,其中高管是根据以下任何一个来挑选的:
轮循 最近最少使用 其他基于优先级的算法
策略模式决定“如何”执行某些操作,状态模式决定“何时”执行这些操作。
这两种模式都委托给一个基类,这个基类有几个派生类,但是只有在State模式中,这些派生类才保留对上下文类的引用。
从另一个角度来看,战略模式是国家模式的简单版本;如果你愿意,也可以称之为子模式。这实际上取决于你是否希望派生状态保留对上下文的引用(即:你是否希望它们调用上下文上的方法)。
更多信息:Robert C Martin (& Micah Martin)在他们的书《c#中的敏捷原则、模式和实践》中回答了这个问题。(http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258)
差异在http://c2.com/cgi/wiki?StrategyPattern中讨论。我使用Strategy模式允许在分析数据的总体框架中选择不同的算法。通过这种方式,您可以添加算法,而不必更改整个框架及其逻辑。
一个典型的例子是你有一个优化函数的框架。框架设置数据和参数。策略模式允许您在不改变框架的情况下选择算法,如最快速下降、共轭梯度、BFGS等。