Design patterns 你永远不会改变策略。o在系统运行期间的状态模式情况下,您可以根据自己的意愿任意更改状态。

Design patterns 你永远不会改变策略。o在系统运行期间的状态模式情况下,您可以根据自己的意愿任意更改状态。,design-patterns,strategy-pattern,state-pattern,Design Patterns,Strategy Pattern,State Pattern,不同之处在于它们解决了不同的问题: 状态模式处理对象是什么(状态或类型)——它封装了依赖于状态的行为,而 策略模式处理对象执行特定任务的方式,它封装了一个算法 然而,实现这些不同目标的结构非常相似;这两种模式都是授权组合的示例 对其优点的一些看法: 通过使用State模式,State holding(context)类不再需要了解它是什么状态或类型以及可用的状态或类型。这意味着该类遵循开放-关闭设计原则(OCP):该类对于存在的状态/类型的更改是关闭的,但状态/类型对扩展是开放的 通过使用

不同之处在于它们解决了不同的问题:

  • 状态模式处理对象是什么(状态或类型)——它封装了依赖于状态的行为,而
  • 策略模式处理对象执行特定任务的方式,它封装了一个算法
然而,实现这些不同目标的结构非常相似;这两种模式都是授权组合的示例


对其优点的一些看法:

通过使用State模式,State holding(context)类不再需要了解它是什么状态或类型以及可用的状态或类型。这意味着该类遵循开放-关闭设计原则(OCP):该类对于存在的状态/类型的更改是关闭的,但状态/类型对扩展是开放的

通过使用策略模式,使用(上下文)类的算法不再需要了解如何执行某项任务(“算法”)。这种情况也造成了对OCP的遵守;对于如何执行此任务的更改,该类已关闭,但该设计非常开放,可以添加其他算法来解决此任务。

这可能还提高了上下文类对单一责任原则(SRP)的遵从性。此外,该算法很容易被其他类重用。

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

  • 状态存储对包含它们的上下文对象的引用。战略不会
  • 允许状态替换自身(即:将上下文对象的状态更改为其他状态),而不允许策略
  • 策略作为参数传递给上下文对象,而状态由上下文对象本身创建
  • 策略只处理单个特定任务,而状态为上下文对象所做的一切(或大多数一切)提供底层实现
一个“经典”的实现将匹配列表中每一项的状态或策略,但您确实遇到了两者混合的混合体。一个特定的系统是状态型还是策略型最终是一个主观问题。

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

  • 工作日
  • 假日
要处理这种情况,可以使用状态模式

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

将客户与支持主管联系起来的这一过程本身可以使用战略模式来实施,在该模式下,根据以下任一方式挑选主管:

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

战略模式决定如何执行某些动作,状态模式决定何时执行动作。

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

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

设计模式并不是真正的“外行”概念,但我会尽可能地把它弄清楚。任何设计模式都可以从三个方面考虑:

  • 模式解决的问题
  • 模式的静态结构(类图)
  • 模式的动态(序列图)
  • 让我们比较一下状态和策略

    模式解决的问题 状态用于以下两种情况之一:

    • 对象的行为取决于其状态,并且它必须在运行时根据该状态更改其行为
    • 操作具有大型多部分条件语句,这些语句依赖于 对象的状态。此状态通常由一个或多个枚举 常数。通常,多个操作将包含相同的条件结构。状态模式将条件的每个分支放在一个单独的类中。这使您可以将对象的状态视为一个独立于其他对象的对象
    如果您想确保确实存在状态模式所解决的问题,那么应该能够使用有限状态机对对象的状态进行建模。您可以找到一个应用示例

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

    我个人还没有发现这种模式有那么大的用处。您总是可以使用查找表实现有限状态机(这不是一种OO方式,但它工作得非常好)

    策略用于以下方面:

    • 许多相关的类只在行为上有所不同。策略提供
      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");
          }
      }
      
      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;
          }
      }
      
      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();
          }
      }