Какова модель стратегии с обратным потоком управления?

В моем понимании шаблон стратегии используется для того, чтобы сделать поведение взаимозаменяемым. Это предполагает, что ответственность за стратегию определяется в интерфейсе, которому клиент затем может делегировать вызовы. Например. предположим, что значение можно получить разными способами, в интерфейсе должен быть метод «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);
    }
  }
}

person Vandhunden    schedule 06.02.2012    source источник
comment
Для меня это выглядит как observer   -  person sll    schedule 06.02.2012
comment
Если вы кодируете немного больше кода в качестве примера, это может помочь. Это даже не обязательно должен быть настоящий код, достаточно псевдокода.   -  person tcarvin    schedule 07.02.2012
comment
Спасибо за ваш ответ. Я попытался сделать пример исходного кода, который иллюстрирует мой случай.   -  person Vandhunden    schedule 07.02.2012
comment
Спасибо за публикацию, это немного помогло!   -  person tcarvin    schedule 08.02.2012


Ответы (2)


Если намерение интерфейса DataSupplier позволить вашему Client подкачивать и делегировать различные конкретные реализации выборки данных, тогда да, это можно считать стратегией. Ваш Client защищен от деталей (также известных как стратегия), используемых для получения значения, как и ожидалось при использовании шаблона стратегии. А то, что в стратегию передается ссылка Client, это нормально и обычно:

(из ГФ)

«Стратегия и контекст взаимодействуют для реализации выбранного алгоритма. Контекст может передавать все данные, требуемые алгоритмом, в стратегию при вызове алгоритма. В качестве альтернативы контекст может передавать себя в качестве аргумента для операций стратегии. Это позволяет Стратегия обратного вызова контекста по мере необходимости».

Контекст для вас Client.

Теперь, когда все сказано, редко встречается решение, использующее только один шаблон. Ваше уведомление, похоже, использует шаблон Observer, как прокомментировал другой автор, и это нормально.

Что мне не нравится в том, что вы реализовали, так это то, что ваша стратегия представляет собой чистый интерфейс. Не всегда плохо, но в этом случае с обратным вызовом уведомления интерфейс не дает гарантии, что обратный вызов уведомления произойдет. Интерфейсы гарантируют только сигнатуры методов. Я бы рекомендовал использовать шаблон Template в базовом классе для получения стратегий.

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;
   }
}

При таком подходе я знаю, что уведомление будет обработано. Мне не нужно беспокоиться о том, что разработчик забудет об этом позже в новой стратегии.

person tcarvin    schedule 07.02.2012
comment
Отличный ответ и совет. Я согласен, что это можно рассматривать как сочетание разных шаблонов. - person Vandhunden; 08.02.2012

Нет. Это не было бы шаблоном стратегии. В шаблоне стратегии интерфейс стратегии и конкретные реализации стратегии ничего не знают о клиенте.

Клиент знает об интерфейсе стратегии и ничего не знает о реальных реализациях.

Целью этого паттерна является возможность замены одной стратегии другой без модификации клиента. Стратегия обычно представляет собой своего рода алгоритм.

То, что вы описываете, похоже, ближе к шаблону проектирования Observer, в котором есть субъект и один или несколько наблюдателей, реализующих общий интерфейс (или наследующий от общего базового класса). Субъект — это объект, за которым наблюдают, а наблюдатели — это объекты, которые должны быть уведомлены всякий раз, когда субъект изменяется. например: субъект может быть каким-то источником данных, а один наблюдатель может быть представлением гистограммы, а другой - представлением круговой диаграммы.

http://en.wikipedia.org/wiki/Observer_pattern
http://en.wikipedia.org/wiki/Strategy_pattern
person xtrem    schedule 07.02.2012