【问题标题】:How does the Strategy Pattern work? [closed]策略模式如何运作? [关闭]
【发布时间】:2010-09-10 15:41:01
【问题描述】:

它是如何工作的,它的用途是什么,什么时候应该使用它?

【问题讨论】:

  • 我建议阅读 Head First - 设计模式的第 1 章。这很好地解释了如何使用它、为什么使用它以及它实际上是如何应用基本的面向对象原则的。它给出了一个具体的(虽然有些有趣)的例子,它真正展示了一个有问题的情况以及策略模式如何解决它。

标签: design-patterns strategy-pattern


【解决方案1】:

让我们以简单的方式解释策略模式:

你有一个类 Car() 和一个方法 run(),所以你在伪语言中以这种方式使用它:

mycar = new Car()
mycar.run()

现在,您可能希望在程序执行时动态更改run() 的行为。例如,您可能想要模拟电机故障或在视频游戏中使用“增强”按钮。

有几种方法可以进行这种模拟:使用条件语句和标志变量是一种方法。策略模式是另一种模式:它将run() 方法的行为委托给另一个类:

Class Car()
{
    this.motor = new Motor(this) 

    // passing "this" is important for the motor so it knows what it is running

    method run()
    {
        this.motor.run()
    }

    method changeMotor(motor)
    {
        this.motor = motor 
    }

}

如果你想改变汽车的行为,你可以改变马达。 (在程序中比在现实生活中更容易,对吧?;-))

如果您有很多复杂的状态,这将非常有用:您可以更轻松地更改和维护它们。

【讨论】:

  • 我喜欢这个答案,所以我投了赞成票,但我认为代码可以更详细。
  • 我知道,这只是为了说明原理。除了读者可以在其他分析器中找到的链接之外,还有大量准确的 sn-ps。
  • +1 很好的例子!一个提示,值得在 changeMotor() 中执行 stopMotor(),只是为了好玩:)
  • 我建议您也添加 Motor 类的代码,它可以帮助更好地理解整体情况。
  • 我很好奇为什么这里没有设计模式?我们可以将其应用到实际工作中,还是因为这只是一个示例?
【解决方案2】:

问题

策略模式用于解决可能(或预计可能)由不同的策略实施或解决的问题,并为此类情况提供明确定义的接口。每个策略本身都是完全有效的,其中一些策略在某些情况下更可取,允许应用程序在运行时在它们之间切换。

代码示例

namespace StrategyPatterns
{
  // Interface definition for a Sort algorithm
  public interface ISort
  {
    void Sort(List<string> list)
  }

  // QuickSort implementation
  public class CQuickSorter : ISort
  {
    void Sort(List<string> list)
    {
      // Here will be the actual implementation
    }
  }

  // BubbleSort implementation
  public class CBubbleSort : ISort
  {
    void Sort(List<string> list)
    {
      // The actual implementation of the sort
    }
  }

  // MergeSort implementation
  public class CMergeSort : ISort
  {
    void Sort(List<string> list)
    {
      // Again the real implementation comes here
    }
  }

  public class Context
  {
    private ISort sorter;

    public Context(ISort sorter)
    {
      // We pass to the context the strategy to use
      this.sorter = sorter;
    }

    public ISort Sorter
    {
      get{return sorter;)
    }
  }

  public class MainClass
  {
    static void Main()
    {
       List<string> myList = new List<string>();

       myList.Add("Hello world");
       myList.Add("Another item");
       myList.Add("Item item");

       Context cn = new Context(new CQuickSorter());
       // Sort using the QuickSort strategy
       cn.Sorter.Sort(myList);
       myList.Add("This one goes for the mergesort");
       cn = new Context(new CMergeSort());
       // Sort using the merge sort strategy
       cn.Sorter.Sort(myList);
    }
  }
}

【讨论】:

  • 这可能只是一个错字,但你的CMergeSort类不应该实现ISort接口吗?
  • 结构图没有了,能更新一下链接吗?
  • 拥有get for ISort in the Context 类有什么用?不确定什么时候有用?
  • Sorter 是私有的,我们可以使用cn.Sorter?
【解决方案3】:
  • 什么是策略?战略是旨在实现特定目标的行动计划;
  • “定义一系列算法,封装每个算法,并使它们可互换。策略让算法独立于使用它的客户而变化。” (四人组);
  • 指定一组类,每个类代表一种潜在的行为。在这些类之间切换会改变应用程序的行为。 (战略);
  • 可以在运行时(使用多态性)或设计时选择此行为;
  • 在接口中捕获抽象,将实现细节隐藏在派生类中;

  • 策略的替代方法是使用条件逻辑更改应用程序行为。 (坏);
  • 使用此模式可以更轻松地添加或删除特定行为,而无需重新编码和重新测试全部或部分应用程序;

  • 好用处:

    • 当我们有一组相似的算法并且它需要在应用程序的不同部分在它们之间进行切换时。使用策略模式可以避免 if 并简化维护;
    • 当我们想向超类添加不一定对每个子类都有意义的新方法时。我们不是以传统方式使用接口,而是添加新方法,而是使用作为新功能接口的子类的实例变量。这称为组合:类不是通过继承来继承能力,而是由具有正确能力的对象组合而成;

【讨论】:

  • 简单而精湛的解释!
  • 策略模式与依赖倒置原则有何不同?
【解决方案4】:

一个密切相关的模式是委托模式;在这两种情况下,一些工作都会传递给其他一些组件。如果我理解正确,这些模式之间的区别是这样的(如果我错了,请纠正我):

  • Delegate 模式中,委托由封闭(委托)类实例化;这允许通过组合而不是继承来重用代码。封闭类可能知道委托的具体类型,例如如果它调用其构造函数本身(而不是使用工厂)。

  • Strategy 模式中,执行策略的组件是通过其构造函数或 setter(根据您的宗教信仰)提供给封闭(使用)组件的依赖项。 using 组件完全不知道正在使用什么策略;策略总是通过接口调用。

有人知道其他区别吗?

【讨论】:

    【解决方案5】:

    直接来自Strategy Pattern Wikipedia article

    策略模式适用于需要动态交换应用程序中使用的算法的情况。策略模式旨在提供一种方法来定义一系列算法,将每个算法封装为一个对象,并使它们可互换。策略模式让算法独立于使用它们的客户端而变化。

    【讨论】:

      【解决方案6】:

      补充已经很精彩的答案:策略模式与将一个(或多个函数)传递给另一个函数非常相似。在策略中,这是通过将所述函数包装在一个对象中,然后传递该对象来完成的。有些语言可以直接传递函数,所以它们根本不需要模式。但是其他语言不能传递函数,但是可以传递对象;然后应用该模式。

      尤其是在类 Java 语言中,您会发现该语言的类型动物园非常小,您扩展它的唯一方法是创建对象。因此,大多数问题的解决方案是提出一个模式;一种组合对象以实现特定目标的方法。具有更丰富类型动物园的语言通常有更简单的解决问题的方法——但更丰富的类型也意味着你必须花更多的时间来学习类型系统。具有动态类型规则的语言通常也会偷偷摸摸地解决问题。

      【讨论】:

      • “类型 zoo”是什么意思?事实证明,这对 Google 来说是一个相当困难的术语。
      • 这是一种类似玩笑的说法,表示该语言没有非常富有表现力的类型系统。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多