在策略模式中,策略能否将Context作为参数 [英] In the strategy pattern can the strategy take the Context as parameter

查看:228
本文介绍了在策略模式中,策略能否将Context作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我现在将关闭该主题(我认为将没有更多反馈)并尝试总结我的理解

I will now close this thead (I think there will be no more feedback) and try to summarize what I understood


  1. 使用上下文作为我策略的参数引入了紧密的耦合,应该避免并且也可能迫使我公开可能应该隐藏在类中的属性。

  2. 为了最大程度地减少耦合,最好提供所需的值,或者至少对接口使用接口而不是具体类型。






我试图清晰地了解策略模式,我要问自己,让策略取决于上下文是好还是坏的设计。


I'm trying to get a clear overview of the strategy pattern and I'm asking myself if it is a good or bad design to have the strategy depends on the context.

让我们采用以下经典实现方式

Let's take the following classical implementation

//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();
  }
}

我看到的所有示例都具有非常简单的策略基本参数(例如整数)。我想知道的是,如果该策略使用上下文执行工作,是否有问题。

All examples I have seen have pretty simple strategies that take basic arguments (integers for example). What I would like to know is if there is something wrong if the strategy uses the Context to do the work.

它会给出类似

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

,调用将得到

//The context
class Context
{
  ....

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

是否要避免这种耦合?可以吗?

Is this "coupling" to be avoided? Is it ok?

推荐答案

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

One issue I see with your approach is that there would a tight coupling between the concrete Context class and the instances of the Strategy classes. This would imply that the Strategy classes can be used only with the Context class . One way to circumvent this is that to make your strategy classes dependent (or use) an interface that the 'Context' class would implement.

EDIT
同样,当Strategy类具有Context类的实例时,这些类也必须从Context类中获取显式数据。这意味着需要在Context类中添加getter(必要时),以使策略类获取所需的数据。但是,添加吸气剂并不一定是一种好的OO操作,因为更多的吸气剂会带来破坏封装的风险。

EDIT Also when the Strategy classes have an instance of Context class, these classes have to get the explicitly data from the Context class. This would mean adding getters (as necessary) in the Context class for strategy classes to get the data they need. But adding getters is not necessarily a good OO practice as more getters pose the risk of breaking the encapsulation.

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

An alternative you can think of is to not pass the reference (this) of Context class to the method(s) in strategy class but to pass only the needed data to the Strategy class.

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

For example if the Context class is something like this: (the code is in 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类时可以使用通用方法,这样 sort 方法不仅适用于Integer,而且适用于通用类型。

In the above code the Strategy class operates on a generic Integer list and is not particularly bound to be used with the Context class. Also taking further one can use a generic method while defining the Strategy class so that sort method is not just applicable to Integers but also to generic types.

这篇关于在策略模式中,策略能否将Context作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆