【问题标题】:What is the difference between Strategy design pattern and State design pattern?策略设计模式和状态设计模式有什么区别?
【发布时间】:2010-12-12 02:33:07
【问题描述】:

策略设计模式和状态设计模式有什么区别?我在网上浏览了很多文章,但无法清楚区分。

有人可以用外行的话解释一下区别吗?

【问题讨论】:

  • 根据这里的答案和我自己的观察,实现似乎在很大程度上(尽管不完全)相同。相反,差异主要在于意图之一:我们试图适应行为,要么基于我们的状态(状态模式),要么基于其他东西(策略模式)。很多时候,其他东西是“客户选择的”,通过注入。

标签: design-patterns strategy-pattern state-pattern


【解决方案1】:

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

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

“经典”实现将匹配列表中每个项目的状态或策略,但您确实会遇到混合了两者的混合体。一个特定的问题是更倾向于 State-y 还是 Strategy-y 最终是一个主观问题。

【讨论】:

  • 如果您将 GoF 视为流行的选择之一,他们会不同意 State 必须由上下文创建(可以由客户端创建并传递到上下文中,就像使用 Strategy )。
【解决方案2】:
  • 策略模式实际上是关于拥有不同的 实现(基本上)完成相同的事情,所以 一种实现可以根据策略需要替换另一种。 例如,您可能有不同的排序算法 策略模式。对象的调用者不会根据 正在采用哪种策略,但无论策略如何,目标 是相同的(对集合进行排序)。
  • State 模式是关于根据 状态,同时让调用者从负担中解脱出来 适应每一种可能的状态。因此,例如,您可能有一个 getStatus() 方法将根据 对象的状态,但方法的调用者不必是 以不同的方式编码以说明每种潜在状态。

【讨论】:

  • 但是谁在策略模式中改变策略??
  • @Noor,通常它是某种参数或字段。实际调用者的代码不会因为策略的改变而改变。
  • @Noor,是的,但是在我现在能想到的任何策略模式中,这将是一个不会在中间改变的预先决定。
  • 我也有同样的问题,状态或策略,我认为几句话的区别是,状态,行为是自动确定的,策略,行为是由调用者确定的。
  • 在电子商务应用中,如果在节日期间需要应用额外的折扣,那就是状态设计模式。如果获得该数字的方法不止一种,则可以将实际的贴现率逻辑与策略设计模式一起应用。
【解决方案3】:

区别仅仅在于它们解决的问题不同:

  • State 模式处理对象的 what(状态或类型)——它封装了依赖于状态的行为,而
  • 策略模式处理如何对象执行特定任务——它封装了一个算法。

然而,实现这些不同目标的结构非常相似;这两种模式都是委托组合的示例。


对其优势的一些观察:

通过使用 State 模式,状态持有(上下文)类从 什么 状态或类型以及可用的状态或类型的知识中解脱出来。这意味着该类遵循开闭设计原则 (OCP):类对状态/类型的变化是封闭的,但状态/类型对扩展是开放的。

通过使用策略模式,算法使用(上下文)类从如何执行特定任务(--“算法”)的知识中解脱出来。这个案例也创建了对 OCP 的遵守;该课程因有关如何执行此任务的更改而关闭,但该设计非常开放,可以添加其他算法来解决此任务。
这也可能提高上下文类对单一责任原则 (SRP) 的遵守。此外,该算法很容易被其他类重用。

【讨论】:

    【解决方案4】:

    谁能通俗点解释一下?

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

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

    让我们比较一下状态和策略。

    模式解决的问题

    State 用于两种情况之一[GoF book p. 306]:

    • 对象的行为取决于其状态,并且它必须在运行时根据该状态更改其行为。
    • 操作具有大型、多部分的条件语句,这些语句依赖于 对象的状态。这种状态通常由一个或多个枚举表示 常数。通常,多个操作将包含相同的条件结构。状态模式将条件的每个分支放在一个单独的类中。这让您可以将对象的状态视为一个可以独立于其他对象变化的对象。

    如果您想确定您确实遇到了状态模式解决的问题,您应该能够使用有限状态机对对象的状态进行建模。您可以找到一个应用示例here

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

    我个人还没有发现这种模式很有用。您始终可以使用查找表来实现有限状态机(这不是 OO 方式,但效果很好)。

    策略用于以下[GoF book p. 316]

    • 许多相关类仅在行为上有所不同。策略提供了一种使用多种行为之一配置类的方法。
    • 您需要算法的不同变体。例如,您可以定义反映不同空间/时间权衡的算法。当这些变体被实现为算法的类层次结构 [HO87] 时,可以使用策略。
    • 算法使用客户端不应该知道的数据。使用策略模式避免暴露复杂的、特定于算法的数据结构。
    • 一个类定义了许多行为,这些行为在其操作中显示为多个条件语句。将相关的条件分支移到它们自己的 Strategy 类中,而不是使用许多条件。

    最后一个应用策略的情况与称为Replace conditional with polymorphism 的重构有关。

    总结:状态和策略解决了截然不同的问题。如果您的问题不能用有限状态机建模,那么状态模式可能不合适。如果您的问题不在于封装复杂算法的变体,则 Strategy 不适用。

    图案的静态结构

    State 具有以下 UML 类结构:

    策略具有以下 UML 类结构:

    总结:就静态结构而言,这两种模式大多相同。事实上,this one 等模式检测工具认为“the structure of the [...] patterns is identical, prohibiting their distinction by an automatic process (e.g., without referring to conceptual information).

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

    模式的动态

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

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

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

    为了显示策略的动态,借用real example很有用。

    总结:每个模式都使用多态调用来根据上下文执行某些操作。在状态模式中,多态调用(转换)经常会导致下一个状态发生变化。在策略模式中,多态调用通常不会改变上下文(例如,使用信用卡支付一次并不意味着您下次将使用 PayPal 支付)。同样,状态模式的动态由其对应的有限状态机决定,这(对我而言)对于正确应用该模式至关重要。

    【讨论】:

    • 这个答案对我帮助我区分差异非常有帮助。状态机参数听起来是相关的恕我直言。这实际上以一种理论计算机科学的方式总结了上述答案。
    • 有一个difference between a state machine and the state pattern。在该模式中,状态必须是多态的:每个状态都呈现相同的 API。在机器中,转换到新状态会导致一组新的操作。因此,模式更侧重于设计状态内的行为,而机器更侧重于设计状态之间的转换。
    【解决方案5】:

    策略模式涉及将算法的实现从托管类移到单独的类中。这意味着宿主类不需要自己提供每个算法的实现,这很可能导致代码不干净。

    排序算法通常用作示例,因为它们都做同样的事情(排序)。如果将每种不同的排序算法放入自己的类中,则客户端可以轻松选择要使用的算法,并且该模式提供了一种访问它的简单方法。

    状态模式涉及在对象状态发生变化时更改对象的行为。这意味着宿主类没有为它可能处于的所有不同状态提供行为的实现。宿主类通常封装一个类,该类提供给定状态所需的功能,并切换到不同的类当状态改变时。

    【讨论】:

      【解决方案6】:

      考虑一个处理客户呼叫的 IVR(交互式语音响应)系统。您可能希望对其进行编程以处理以下客户:

      • 工作日
      • 节假日

      要处理这种情况,您可以使用状态模式

      • 假日:IVR 只是回复说“只能在工作日的上午 9 点到下午 5 点之间接听电话”。
      • 工作日:它通过将客户与客户服务主管联系起来做出回应。

      这个将客户与支持主管联系起来的过程本身可以使用战略模式来实现,其中主管是根据以下任何一项来挑选的:

      • 循环赛
      • 最近最少使用
      • 其他基于优先级的算法

      策略模式决定“如何”执行某些操作,状态模式决定“何时”执行这些操作。

      【讨论】:

      • 这是一个很好的答案,但被低估了。但是,在您的示例中提及为什么需要许多算法会很有帮助。例如,算法是根据呼叫中心公司的偏好来选择的。如果您的列表中有更简单或琐碎的算法对于那些不了解 RR 或 LRU 的人来说也会有所帮助。例如 - 时间长的客户获得更高的优先级,等待时间最长的客户获得更高的优先级。谢谢!
      • 哇!我真的推荐这个答案。您所处的当前模式 .... VS .... 通过算法制定的行动计划!
      【解决方案7】:

      策略表示“做”某事的对象,具有相同的开始和结束结果,但在内部使用不同的方法。从这个意义上说,它们类似于表示动词的实现。状态模式 OTOH 使用“是”某物的对象 - 操作的状态。虽然它们也可以表示对该数据的操作,但它们更类似于表示名词而不是动词,并且是针对状态机量身定制的。

      【讨论】:

        【解决方案8】:

        策略:策略是固定的,通常由几个步骤组成。 (排序仅构成一个步骤,因此是一个非常糟糕的示例,因为它太原始而无法理解此模式的目的)。 您在策略中的“主要”例程正在调用一些抽象方法。例如。 “进入房间策略”,“main-method”是goThroughDoor(),看起来像:accessDoor(), if (locked()) openLock();开门();进入房间();转动();关门(); if (wasLocked()) lockDoor();

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

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

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

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

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

        例如你有一个登录服务。它接受用户名和密码。它只有一种方法:logon(String userName, String passwdHash)。它不是自己决定是否接受登录,而是将决定委托给状态对象。该状态对象通常只检查用户/密码组合是否有效并执行登录。但是现在您可以将“检查器”更换为只允许特权用户登录(例如在维护期间)或不允许任何人登录的“检查器”。这意味着“检查器”表示系统的“登录状态”。

        最重要的区别是:当你选择了一个策略后,你会坚持下去,直到你完成它。这意味着您将其称为“主要方法”,只要该方法正在运行,您就永远不会更改策略。 OTOH 在系统运行期间的状态模式情况下,您可以随意更改状态。

        【讨论】:

          【解决方案9】:

          策略模式用于特定任务有多种算法并且客户端决定在运行时使用的实际实现。

          UML图来自wiki策略模式文章:

          主要特点:

          1. 这是一种行为模式。
          2. 它基于委托。
          3. 它通过修改方法行为来改变对象的内部结构。
          4. 用于在一系列算法之间切换。
          5. 它会在运行时更改对象的行为。

          有关更多信息和真实示例,请参阅此帖子:

          Real World Example of the Strategy Pattern

          状态模式允许对象在其内部状态改变时改变其行为

          UML图来自wiki状态模式文章:

          如果我们必须根据状态改变对象的行为,我们可以在对象中拥有一个状态变量,并使用 if-else 条件块来根据状态执行不同的操作。 State 模式用于通过 ContextState 实现提供一种系统的、丢失耦合的方式来实现这一点。

          有关详细信息,请参阅这篇journaldev 文章。

          sourcemakingjournaldev 文章的主要区别:

          1. StateStrategy的区别在于绑定时间。 策略是一次绑定模式,而状态是动态的
          2. StateStrategy 的区别在于意图。 使用 Strategy,算法的选择是相当稳定的对于 State,“上下文”对象的状态变化会导致它从 Strategy 对象的“调色板”中进行选择
          3. Context 包含状态作为实例变量,并且可以有多个任务的实现可以依赖于 state 而在 strategy 模式中 strategy 作为参数传递给方法,而 context 对象没有任何变量来存储它。

          【讨论】:

            【解决方案10】:

            通俗地说,

            在策略模式中,没有状态或所有状态都具有相同的状态。 所有人都有不同的方式来完成一项任务,就像不同的医生以不同的方式对待同一病人的同一疾病一样。

            在状态模式中,主观上存在状态,例如患者的当前状态(例如高温或低温),将根据其决定下一步的行动(药物处方)。并且一种状态可以导致另一种状态,所以存在状态到状态的依赖关系(技术上的组合)。

            如果我们从技术上尝试理解它,基于两者的代码比较,我们可能会失去情况的主观性,因为两者看起来非常相似。

            【讨论】:

            • 点赞!这是非常好的解释!谢谢! :)
            【解决方案11】:

            状态在状态派生类中带有一点依赖关系:就像一个状态知道其他状态在它之后。例如,对于任何季节状态,Summer 在冬季之后出现,或者对于购物,Delivery 状态在Deposit 状态之后。

            另一方面,Strategy 没有这样的依赖项。在这里,可以根据程序/产品类型初始化任何类型的状态。

            【讨论】:

              【解决方案12】:

              这两种模式都委托给具有多个派生类的基类,但只有在状态模式中,这些派生类才会引用回上下文类。

              另一种看待它的方式是,策略模式是状态模式的更简单版本;一个子模式,如果你喜欢的话。这实际上取决于您是否希望派生状态保留对上下文的引用(即:您是否希望它们调用上下文中的方法)。

              更多信息:Robert C Martin (& Micah Martin) 在他们的书“C# 中的敏捷原则、模式和实践”中回答了这个问题。 (http://www.amazon.com/Agile-Principles-Patterns-Practices-C/dp/0131857258)

              【讨论】:

                【解决方案13】:

                策略模式和状态模式具有相同的结构。如果您查看两种模式的 UML 类图,它们看起来完全相同,但它们的意图完全不同。状态设计模式用于定义和管理对象的状态,而策略模式用于定义一组可互换的算法并让客户选择其中一个。所以策略模式是客户端驱动的模式,而对象可以自己管理状态。

                【讨论】:

                  【解决方案14】:

                  这是一个相当古老的问题,但我仍然在寻找相同的答案,这就是我发现的。

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

                  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

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

                  但不同之处在于它们的用途是状态模式,用于根据对象的状态执行不同的逻辑。并且在策略不同逻辑的情况下。

                  【讨论】:

                    【解决方案15】:

                    http://c2.com/cgi/wiki?StrategyPattern 中讨论了差异。我使用了策略模式来允许在分析数据的整体框架内选择不同的算法。通过它,您可以添加算法,而无需更改整体框架及其逻辑。

                    一个典型的例子是你有一个优化函数的框架。框架设置数据和参数。策略模式允许您在不改变框架的情况下选择最速下降、共轭梯度、BFGS 等算法。

                    【讨论】:

                      【解决方案16】:

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

                      【讨论】:

                        【解决方案17】:

                        正如*所说的状态模式:

                        状态模式是一种行为软件设计模式,它允许 对象在其内部状态发生变化时改变其行为。这 模式接近于有限状态机的概念。

                        让我们谈谈现实世界的例子,它是汽车的方向盘。方向盘可以更换。我们可以设置更大或更小的方向盘。但是,我们认为小方向盘比大方向盘对汽车前轮的夹角更大,这不是一个规则。

                        因此,我们可以得出结论,我们的汽车的行为会因我们设置的转向工具而异。例如,如果我们设置较小的方向盘,我们的汽车会向左或向右转得更快。

                        因此,汽车会响应TurnLeft()TurnRight() 等事件。但是,汽车车轮可以转动的角度取决于当前选择的方向盘。让我们尝试编码:

                        public interface ISteeringWheel
                        {
                            void TurnLeft();
                            void Straight();
                            void TurnRight();
                        }
                        
                        
                        public class BigSteeringWheel : ISteeringWheel
                        {
                            public void Straight()
                            {
                              Console.WriteLine("BigSteeringWheel is straight");
                            }
                         
                            public void TurnLeft()
                            {
                                Console.WriteLine("BigSteeringWheel is turned left 10  
                                    degrees");
                            }
                        
                            public void TurnRight()
                            {
                                Console.WriteLine("BigSteeringWheel is turned right 10  
                                    degrees");
                            }
                        }
                        
                        
                        public class SmallSteeringWheel : ISteeringWheel
                        {
                            public void Straight()
                            {
                                Console.WriteLine("SmallHandleBar is straight");
                            }
                        
                            public void TurnLeft()
                            {
                                Console.WriteLine("SmallHandleBar is turned left 
                                   20 degrees");
                            }
                            public void TurnRight()
                            {
                                Console.WriteLine("SmallHandleBar is turned right 20  
                                    degrees");
                            }
                        }
                        

                        Automobile 类:

                        public class Automobile
                        {
                            public ISteeringWheel SteeringWheel { get; private set; }
                        
                            public Automobile()
                            {
                                SteeringWheel = new BigSteeringWheel();
                            }
                            public void TurnLeft()
                            {
                                 SteeringWheel.TurnLeft();
                            }
                            
                            public void TurnRight()
                            {
                                SteeringWheel.TurnRight();
                            }
                        
                            public void SetSteeringWheel(ISteeringWheel handleBar)
                            {
                                SteeringWheel = handleBar;
                            }
                        }
                        

                        策略模式:

                        来自*的定义:

                        策略模式(也称为策略模式)是一种 能够选择算法的行为软件设计模式 在运行时。不是直接实现单个算法,而是代码 接收关于在一系列算法中的哪一个的运行时指令 使用。

                        注意诸如«family of algorithm to use»之类的词。所以让我们假设我们有一辆真正的汽车,当驾驶员向左转动方向盘时,我们希望我们的汽车会执行以下操作:

                        • 将汽车车轮向左转 10 度
                        • 打开汽车左侧橙色信号

                        因此,以上两个动作可以被视为«家庭算法使用»。 让我们编写这个例子。

                        方向盘算法:

                        public interface ISteeringWheel
                        {
                            void TurnLeft();
                            void Straight();
                            void TurnRight();
                        }
                        
                        public class BigSteeringWheel : ISteeringWheel
                        {
                            public void Straight()
                            {
                                Console.WriteLine("BigSteeringWheel is straight");
                            }
                         
                            public void TurnLeft()
                            {
                                Console.WriteLine("BigSteeringWheel is turned left 
                                   10 degrees");
                            }
                            public void TurnRight()
                            {
                                Console.WriteLine("BigSteeringWheel is turned right 
                                    10 degrees");
                            }
                        }
                        

                        转向灯算法:

                        public interface ITurnSignal
                        {
                            void TurnOnLeft();
                            void TurnOnRight();
                        }
                        
                        public class OrangeTurnSignal : ITurnSignal
                        {
                            public void TurnOnLeft()
                            {
                                Console.WriteLine("Left OrangeTurnSignal is turned on");
                            }
                            public void TurnOnRight()
                            {
                                Console.WriteLine("Right OrangeTurnSignal is turned on");
                            }
                        }
                        

                        还有汽车类:

                        public class Automobile
                        {
                            public ISteeringWheel SteeringWheel { get; private set; }
                            public ITurnSignal TurnSignal { get; private set; }
                        
                            public Automobile()
                            {
                                SteeringWheel = new BigSteeringWheel();
                                TurnSignal = new OrangeTurnSignal();
                            }
                            public void TurnLeft()
                            {
                                SteeringWheel.TurnLeft();
                                TurnSignal.TurnOnLeft();
                            }
                        
                            public void TurnRight()
                            {
                                SteeringWheel.TurnRight();
                                TurnSignal.TurnOnRight();
                            }
                        }
                        

                        结论:

                        State patternStrategy pattern 看起来非常相似。但是,State pattern 有一个单一状态,并且所有的行为,如 «TurnLeft» 和 «TurnRight» 都封装在一个类中,这有一个微小的区别。另一方面,Strategy pattern 没有单一状态,但它有许多状态,例如«SteeringWheel»和«TurnSignal»。这些不同的行为使用不同的策略对象进行封装,例如 «SteeringWheel» 和 «TurnSignal» 对象。因此,这是状态模式和策略模式之间的主要区别。

                        此外,我们可以将Strategy pattern 视为子类化的一个很好的替代方案。继承为我们提供了类之间非常紧密的耦合,并且类之间的这种耦合是在编译时定义的。但是,Strategy pattern 使用的组合允许在运行时通过与不同的对象组合来设置行为。

                        State pattern 也可以被视为替代类中许多if — else 语句的替代方案。

                        【讨论】:

                          【解决方案18】:

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

                          任务 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 中使用不同的算法组合来拥有更多状态。状态模式允许您从一种状态切换到另一种状态并执行不同的算法组合。

                          【讨论】:

                            【解决方案19】:

                            “策略”只是一种算法,您可以根据需要在不同情况下更改它,它会为您处理一些事情。 前任。您可以选择如何压缩文件。 zip 或 rar ... 在一个方法中。

                            但是“状态”可以改变你所有的对象行为,当它改变时, 甚至它也可以更改其他字段……这就是它引用其所有者的原因。您应该注意到,更改对象字段完全可以更改对象行为。 前任。当您将 obj 中的 State0 更改为 State1 时,您会将一个整数更改为 10.. 所以当我们调用 obj.f0() 进行一些计算并使用该整数时,它会影响结果。

                            【讨论】:

                              【解决方案20】:

                              这两种模式都用于改变对象的行为,

                              根据设计,状态模式对象具有单一状态,对象的行为基于实现的单一状态(类)及其子类。

                              相比之下,策略没有单一的状态,一个对象的行为是由不同策略对象的实现决定的。

                              【讨论】:

                                【解决方案21】:
                                1. 在实现搜索的策略模式中,我们可以有 多种搜索策略,例如NaiveStrategy()KMPStrategy()RabinKarp() 策略。这些都是独立的并且有 比较稳定的选择。最重要的是,战略不能改变 从彼此。只有Context 能够改变策略。
                                2. 另一方面,状态模式基于Finite-State 的概念 Machines。这些状态可以相互转换。这里说 与策略相比,稳定性较差。还有一件事,每个 具体状态保持对context 的引用,因此能够 转换到另一个状态。

                                所以关键在于,在策略中,只有上下文可以设置策略,而在状态模式的情况下,状态可以执行到其他状态的转换。策略模式中的策略不知道彼此。虽然状态在状态模式中并非不知道彼此,并允许在它们保持对上下文对象的引用时进行转换。

                                “策略使这些对象完全独立并且彼此不知道。但是,State 并不限制具体状态之间的依赖关系,让它们随意改变上下文的状态。”

                                参考:https://refactoring.guru/design-patterns/strategy

                                【讨论】:

                                  最近更新 更多