策略模式与状态模式之间有什么区别?我查阅了很多文章,但是仍然不能清楚地区分它们的不同。
请问有人能用通俗易懂的语言来解释它们之间的区别吗?
策略模式与状态模式之间有什么区别?我查阅了很多文章,但是仍然不能清楚地区分它们的不同。
请问有人能用通俗易懂的语言来解释它们之间的区别吗?
策略模式和状态模式具有相同的结构。如果你查看这两种模式的UML类图,它们看起来完全相同,但它们的意图却完全不同。状态设计模式用于定义和管理对象的状态,而策略模式用于定义一组可互换的算法,并让客户端选择其中一个。因此,策略模式是一种客户端驱动的模式,而对象可以自己管理其状态。
状态模式的派生类之间存在一些依赖关系:例如,一个状态知道在它之后出现的其他状态。例如,对于任何季节状态,夏季在冬季之后,或者对于购物,交付状态在存款状态之后。
另一方面,策略模式没有这样的依赖关系。在这里,可以根据程序/产品类型初始化任何类型的状态。
https://www.youtube.com/watch?v=e45RMc76884 https://www.tutorialspoint.com/design_pattern/state_pattern.htm
在策略模式的情况下,类图的安排与状态模式相同。客户端使用此安排执行某些操作。换句话说,不同的状态变为不同的算法,例如需要对模式执行不同的分析。在这里,客户端告诉上下文它想要做什么算法(业务定义的自定义算法),然后执行该算法。https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm
这两个模式都遵循开闭原则,因此开发者可以向状态模式和策略模式中添加新的状态和算法。
但是它们的区别在于,状态模式用于根据对象的状态执行不同的逻辑,而策略模式用于执行不同的逻辑。
我们对一些声音策略的抽象:
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");
}
}
这是一个能够发出声音的动物的抽象类:
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
有一定的可能性你想要改变你的策略
假设你有一个电脑游戏,主人公可以是世界上任何超级人物,我们把他称为Hero
, 他能够奔跑、游泳和飞行,并可以变形为IronMan
或SpiderMan
。您有一个按钮可以将其形状或状态更改为IronMan
或SpiderMan
。
Hero 的代码看起来像这样:
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();
}
}
Hero
类的按钮 ChangeShape()
,您将能够将英雄的 State
从例如 SpiderMan
改变为 IronMan
。Hero
)的状态取决于并可以通过其按钮 ChangeShape
进行更改。这可以发生多次。State
模式也可以被视为替换类中许多 if - else
语句的替代方案。这个区别在http://c2.com/cgi/wiki?StrategyPattern上进行了讨论。我使用策略模式允许在整体框架内选择不同的算法来分析数据,通过这种方式,你可以添加算法而不必改变整体框架及其逻辑。
一个典型的例子是,你可能有一个优化函数的框架,该框架设置数据和参数。策略模式允许你选择算法,例如最陡下降法、共轭梯度法、BFGS等,而不会改变框架本身。
这两种模式都用于改变对象的行为。
按照设计,状态模式对象只有一个状态,对象的行为基于实现的单个状态(类)及其子类。
相比之下,策略模式没有单一状态,对象的行为取决于不同策略对象的实现。
但是'状态'可以改变所有对象的行为,当它发生变化时, 甚至它可以改变其他领域...这就是为什么它具有对其所有者的引用。您应该注意,更改对象字段会完全改变对象行为。 例如,当您将obj中的State0更改为State1时,您将一个整数更改为10..因此,当我们调用obj.f0()执行某些计算并使用该整数时,它会影响结果。
"