逆流控制的策略模式是什么?

时间:2012-02-06 13:29:58

标签: oop design-patterns observer-pattern strategy-pattern

在我的理解中,策略模式用于使行为可互换。这涉及策略的职责在接口中定义,然后客户端可以委托呼叫。例如。假设一个值可以通过不同的方式获得,接口将有一个方法“getValue()”。

我的问题涉及控制流程相反的情况。例如,如果具体策略在客户端上启动请求“onValueChanged()”(假设它具有对客户端或回调接口的引用)。

这仍然被视为策略模式吗?

更新 - 添加了以下源代码示例:

interface DataSupplierCb
{
  void onValueChanged(int a);
}

interface DataSupplier
{
  void check();
}

// NOTE 1: Data supplier knows how the get the value
class ConcreteDataSupplier : public DataSupplier
{
  void check()
  {        
    myDataSupplierCb.onValueChanged(47);
  }
}

class Client : public DataSupplierCb
{
  void onValueChanged(int a)
  {
    // NOTE 2: Client knows what to do with the value
  }

  void changeDataSupplier(int i)
  {
    if (i == 1)
    {
      myCurrentDataSupplier = new ConcreteDataSupplier(this);
    }
  }
}

2 个答案:

答案 0 :(得分:2)

没有。这不是战略模式。在策略模式中,策略接口和具体策略实现不了解客户端。

客户端知道策略接口,并且对实际实现一无所知。

此模式的目标是在不修改客户端的情况下将一个策略替换为另一个策略的能力。策略通常是某种算法。

您所描述的内容似乎更接近Observer设计模式,其中有一个主题和一个或多个观察者实现一个公共接口(或从一个公共基类继承)。主题是正在观察的对象,观察者是在主题发生变化时需要通知的对象。例如:主题可以是某种数据源,一个观察者可以是直方图视图,另一个是饼图视图。

http://en.wikipedia.org/wiki/Observer_pattern
http://en.wikipedia.org/wiki/Strategy_pattern

答案 1 :(得分:1)

如果DataSupplier接口的 intent 允许您的Client交换,并委托给不同的具体数据获取实现,那么可以认为是战略。您的Client屏蔽了用于在使用策略模式时按预期获取值的详细信息(也称为策略)。而Client引用传递给策略的事实很好而且很常见:

(来自GoF)

  

“策略和上下文相互作用以实现所选择的算法   上下文可以将算法所需的所有数据传递给策略   当算法被调用时。 或者,上下文可以通过   本身作为战略行动的一个论据。这就是策略   根据需要回复上下文。“

您的上下文是Client

现在所有人都说,罕见的是只使用一种模式的解决方案。您的通知似乎确实使用了观察者模式作为另一张评论的海报,这很好。

我对你所实施的内容不喜欢的是你的策略是一个纯粹的界面。并不总是坏事,但在这个的情况下,通过该通知回调,接口不能保证通知回调将会发生。接口仅保证方法签名。我建议在基类中使用模板模式来驱逐策略。

abstract class DataSupplier
{

   protected ClientInterface _client;

   // ctor takes in context
   public DataSupplier(ClientInterface client)
   {
      _client - client;
   }

   public void check()
   {
      int priorValue = 46;

      int newValue = OnGetValue(); 

      if (priorValue != newValue)
         _client.onValueChanged(newValue)

   }

   protected abstract int OnCheck();

}

然后:

class ConcreteDataSupplier : DataSupplier
{

   // Check, and notification, are handled by the base.  We only need
   // to implement the actually data fetching

   int OnGetValue()
   {        
      return someValue;
   }
}

通过这种方法,我知道将处理通知。我不需要担心实现者会在以后的新策略中忘记它。