战略设计模式和国家设计模式之间的区别是什么?我在网上浏览了不少文章,但看不出明显的区别。

有人能用外行的语言解释一下吗?


当前回答

简而言之,使用策略模式,我们可以动态地设置一些行为,使用状态模式,我们可以确定,对象将随着状态的变化而在内部改变其行为。

其他回答

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

“策略”只是一种算法,你可以根据自己的需要在不同的情况下改变它,它为你处理一些事情。 例如,你可以选择如何压缩一个文件。Zip or rar…在一个方法中。

但是“状态”可以改变你所有的对象行为,当它改变时, 甚至它也能改变其他领域……这就是为什么它有一个指向它的主人的引用。您应该注意到,改变对象字段完全可以改变对象行为。 例如,当你在obj中将stat0更改为State1时,你将一个整数更改为10。因此,当我们调用obj.f0()进行一些计算并使用该整数时,它会影响结果。

老实说,这两种模式在实践中非常相似,它们之间的定义差异往往取决于你问谁。一些流行的选择是:

状态存储对包含它们的上下文对象的引用。战略则不然。 状态可以替换自己(IE:将上下文对象的状态更改为其他状态),而策略则不能。 策略作为参数传递给上下文对象,而状态由上下文对象本身创建。 策略只处理一个特定的任务,而状态为上下文对象所做的所有(或几乎所有)事情提供底层实现。

一个“经典”的实现将匹配列表中的每个道具的状态或策略,但你也会遇到混合了两者的情况。具体是国家层面的还是战略层面的,最终是一个主观问题。

这是一个相当老的问题,但我也在寻找同样的答案,这就是我所发现的。

对于状态模式,让我们考虑一个中间播放器播放按钮的例子。当我们开始播放时,它开始播放,并让上下文意识到它正在播放。每次客户端想要执行播放操作时,他都会检查播放器的当前状态。现在客户端知道对象的状态是通过上下文对象播放的,所以他调用暂停状态对象的动作方法。客户端实现状态的部分以及它需要在什么状态上执行操作的部分可以被自动化。

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

两者都实现了开闭原则,因此开发人员可以向状态模式和新算法中添加新的状态。

但不同之处在于它们使用的是基于对象状态执行不同逻辑的状态模式。在战略的案例中有不同的逻辑。

策略:策略是固定的,通常由几个步骤组成。(排序只构成了一个步骤,因此是一个非常糟糕的例子,因为它太原始了,无法理解此模式的目的)。 策略中的“主”例程调用了一些抽象方法。如。“进入房间策略”,“main-method”是goThroughDoor(),它看起来像:approachDoor(), if (locked()) openLock();openDoor ();enterRoom ();把();closeDoor ();if (wasLocked()) lockDoor();

现在,这个通用“算法”的子类可以实现该算法的步骤,该算法用于通过可能锁着的门从一个房间移动到另一个房间。

换句话说,策略子类化不会改变基本算法,只会改变单个步骤。

上面是一个模板方法模式。现在把属于一起的步骤(解锁/锁定和打开/关闭)放到它们自己的实现对象中,并委托给它们。例如,带钥匙的锁和带码卡的锁是两种锁。将策略委托给“Step”对象。现在您有了一个策略模式。

状态模式是完全不同的东西。

你有一个包装对象和被包装的对象。被包装的是“状态”。状态对象只能通过它的包装器访问。现在您可以随时更改包装对象,因此包装器似乎可以更改其状态,甚至更改其“类”或类型。

E.g. you have a log on service. It accepts a username and a password. It only has one method: logon(String userName, String passwdHash). Instead of deciding for itself whether a log on is accepted or not, it delegates the decision to a state object. That state object usually just checks if the user/pass combination is valid and performs a log on. But now you can exchange the "Checker" by one that only lets priviledged users log on (during maintanace time e.g.) or by one that lets no one log on. That means the "checker" expresses the "log on status" of the system.

最重要的区别是:当你选择了一种策略,你要坚持它,直到你完成它。这意味着你调用它的“主方法”,只要它在运行,你就永远不会改变策略。OTOH在系统运行时的状态模式情况下,您可以随意更改您认为合适的状态。