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

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


当前回答

当你有一个可以分为两个任务的项目时:

任务1:您可以使用两种不同的算法之一来完成:alg1, alg2

任务2:您可以使用三种不同的算法之一来完成:alg3, alg4, alg5

Alg1和alg2是可互换的;Alg3、alg4和alg5是可以互换的。

在任务1和任务2中选择哪种算法取决于状态:

状态1:任务1中需要alg1,任务2中需要alg3

状态2:任务1中需要alg2,任务2中需要alg5

上下文可以将状态对象从状态1更改为状态2。然后,您的任务将由alg2和alg5完成,而不是alg1和alg3。

您可以为任务1或任务2添加更多可互换的算法。这就是战略模式。

你可以在任务1和任务2中使用不同的算法组合获得更多的状态。状态模式允许从一种状态切换到另一种状态,并执行不同的算法组合。

其他回答

The Strategy pattern is really about having a different implementation that accomplishes (basically) the same thing, so that one implementation can replace the other as the strategy requires. For example, you might have different sorting algorithms in a strategy pattern. The callers to the object does not change based on which strategy is being employed, but regardless of strategy the goal is the same (sort the collection). The State pattern is about doing different things based on the state, while leaving the caller relieved from the burden of accommodating every possible state. So for example you might have a getStatus() method that will return different statuses based on the state of the object, but the caller of the method doesn't have to be coded differently to account for each potential state.

策略:策略是固定的,通常由几个步骤组成。(排序只构成了一个步骤,因此是一个非常糟糕的例子,因为它太原始了,无法理解此模式的目的)。 策略中的“主”例程调用了一些抽象方法。如。“进入房间策略”,“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在系统运行时的状态模式情况下,您可以随意更改您认为合适的状态。

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

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

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

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

设计模式并不是真正的“门外汉”概念,但我将尽量使其清楚。任何设计模式都可以从三个维度来考虑:

模式解决的问题; 模式的静态结构(类图); 模式的动态(序列图)。

让我们比较国家和战略。

模式解决的问题

State有两种用法[GoF book p. 306]:

An object's behavior depends on its state, and it must change its behavior at run-time depending on that state. Operations have large, multipart conditional statements that depend on the object's state. This state is usually represented by one or more enumerated constants. Often, several operations will contain this same conditional structure. The State pattern puts each branch of the conditional in a separate class. This lets you treat the object's state as an object in its own right that can vary independently from other objects.

如果您希望确保您确实存在状态模式解决的问题,那么您应该能够使用有限状态机对对象的状态进行建模。你可以在这里找到一个应用的例子。

每个状态转换都是state接口中的一个方法。这意味着对于设计来说,在应用此模式之前必须非常确定状态转换。否则,如果您添加或删除转换,则需要更改接口和实现它的所有类。

我个人认为这种模式并不有用。您总是可以使用查找表实现有限状态机(这不是面向对象的方法,但它工作得非常好)。

策略用于以下[GoF书第316页]:

many related classes differ only in their behavior. Strategies provide a way to configure a class with one of many behaviors. you need different variants of an algorithm. For example, you might define algorithms reflecting different space/time trade-offs. Strategies can be used when these variants are implemented as a class hierarchy of algorithms [HO87]. an algorithm uses data that clients shouldn't know about. Use the Strategy pattern to avoid exposing complex, algorithm-specific data structures. a class defines many behaviors, and these appear as multiple conditional statements in its operations. Instead of many conditionals, move related conditional branches into their own Strategy class.

在哪里应用Strategy的最后一种情况与称为用多态性替换条件的重构有关。

总结:国家和战略解决的问题完全不同。如果您的问题不能用有限状态机建模,那么可能的状态模式就不合适。如果您的问题不是关于封装复杂算法的变体,那么Strategy就不适用。

模式的静态结构

State具有以下UML类结构:

Strategy具有以下UML类结构:

总结:就静态结构而言,这两种模式基本相同。事实上,像这样的模式检测工具认为“的结构 […]模式是相同的,禁止他们 通过自动过程进行区分(例如,不引用 到概念信息)。”

但是,如果ConcreteStates自己决定状态转换(参见上图中的“可能决定”关联),那么就会有很大的不同。这导致了具体状态之间的耦合。例如(请参阅下一节),状态A决定到状态b的转换。如果Context类决定到下一个具体状态的转换,这些依赖关系就消失了。

模式的动态性

正如上面的Problem部分所提到的,State意味着行为在运行时根据对象的某些状态而改变。因此,状态转换的概念适用于有限状态机的关系。[GoF]提到转换可以定义在ConcreteState子类中,也可以定义在一个集中的位置(比如基于表的位置)。

让我们假设一个简单的有限状态机:

假设子类决定状态转换(通过返回下一个状态对象),动态看起来像这样:

为了展示《战略》的动态,我们可以借用一个真实的例子。

Summary: Each pattern uses a polymorphic call to do something depending on the context. In the State pattern, the polymorphic call (transition) often causes a change in the next state. In the Strategy pattern, the polymorphic call does not typically change the context (e.g., paying by credit card once doesn't imply you'll pay by PayPal the next time). Again, the State pattern's dynamics are determined by its corresponding fininte state machine, which (to me) is essential to correct application of this pattern.

状态在状态派生类中有一点依赖关系:就像一个状态知道接下来的其他状态。例如,对于任何季节状态,夏天在冬天之后,或者对于购物,交付状态在存款状态之后。

另一方面,策略没有这样的依赖关系。在这里,任何类型的状态都可以基于程序/产品类型进行初始化。