12

反馈总结

我现在将关闭此标题(我认为不会有更多反馈)并尝试总结我所理解的内容

  1. 使用“上下文”作为我的策略的参数引入了应该避免的紧密耦合,并且还可能迫使我公开可能应该隐藏在类中的属性。
  2. 为了最小化耦合,最好为策略提供所需的值或至少使用接口而不是具体类型。

我试图对策略模式有一个清晰的概述,并且我在问自己,让策略取决于上下文是一个好还是坏的设计。

让我们采取以下经典实现

//The strategy
interface IStrategy  
{  
  void Execute();  
}  

class ConcreteStrategyA : IStrategy
{
  public void Execute()
  {
    Console.WriteLine( "Called ConcreteStrategyA.Execute()" );
  }
}

class ConcreteStrategyB : IStrategy
{
  public void Execute()
  {
    Console.WriteLine( "Called ConcreteStrategyB.Execute()" );
  }
}

//The context
class Context
{
  IStrategy strategy;

  // Constructor
  public Context(IStrategy strategy)
  {
    this.strategy = strategy;
  }

  public void UpdateContext(IStrategy strategy)
  {
    this.strategy = strategy;
  }

  public void Execute()
  {
    strategy.Execute();
  }
}

我见过的所有示例都有非常简单的策略,它们采用基本参数(例如整数)。我想知道的是,如果策略使用 Context 来完成工作,是否有问题。

它会给出类似的东西

//The strategy
interface IStrategy  
{  
  void Execute(Context arg);  
}  

并且调用会给出

//The context
class Context
{
  ....

  public void Execute()
  {
    strategy.Execute(this);
  }
}

这种“耦合”要避免吗?可以吗?

4

4 回答 4

7

我在您的方法中看到的一个问题是,具体的Context类和 Strategy 类的实例之间存在紧密耦合。这意味着 Strategy 类只能与 Context 类一起使用。避免这种情况的一种方法是使您的策略类依赖(或使用)“上下文”类将实现的接口。

编辑 此外,当 Strategy 类具有 Context 类的实例时,这些类必须从 Context 类中获取显式数据。这意味着在 Context 类中为策略类添加 getter(根据需要)以获取他们需要的数据。但是添加 getter 不一定是一个好的 OO 实践,因为更多的 getter 会带来破坏封装的风险。

您可以想到的另一种选择是将 Context 类的引用 (this) 传递给策略类中的方法,而仅将所需的数据传递给 Strategy 类。

例如,如果 Context 类是这样的:(代码在 Java 中)

Context {
   IStrategy strategy;
   List<Integer> scores;

   public Context(IStrategy strategy)
   {
        this.strategy = strategy;
        scores = new ArrayList<Integer>
   }

   public print() {
       strategy.sort(scores);
   }
}

public interface IStrategy<Integer> {
    public void sort(List<Integer> l);
}

在上面的代码中,Strategy 类在一个通用的 Integer 列表上进行操作,并且并不一定要与 Context 类一起使用。还可以在定义 Strategy 类时使用泛型方法,以便排序方法不仅适用于整数,还适用于泛型类型。

于 2010-01-09T18:09:20.860 回答
5

恕我直言,没关系。但我更喜欢通过策略实现类的构造函数将上下文传递给策略。

于 2010-01-09T17:57:55.893 回答
2

你的代码就是你的代码,写任何对你有意义的东西。但是,我确实有一点警告。

策略模式的目的是创建一系列可以互换的策略。像许多设计模式一样,它从解耦中受益。在这种情况下,我们将行为与使用此类行为的类分离。

当策略将上下文作为参数时,解耦就会减少。上下文的变化可能需要改变你的策略实施。就像之前的海报指出的那样,最好寻找一种方法使它们保持分离。

话虽如此,只要您的意图是允许策略可互换并且您的代码实现了该意图,那么我看不出问题。

于 2010-01-09T22:32:37.900 回答
0

根据这本书,有几种方法,包括你的:

在此处输入图像描述

于 2020-07-29T02:25:12.560 回答