Передача данных между объектами в схеме Chain of Responsibility - PullRequest
4 голосов
/ 18 марта 2011

При реализации шаблона Цепочка ответственности я столкнулся с дилеммой о том, как передавать данные между объектами в цепочке.Типы данных, передаваемые между объектами в цепочке, могут отличаться для каждого объекта.В качестве временного исправления я создал класс Static, содержащий стек, где каждый объект в цепочке может помещать результаты в стек, в то время как следующий объект в цепочке может извлекать результаты из стека.Вот пример кода того, что я реализовал.

public interface IHandler
{        
  IHandler Successor {get; set; }
  void Process();        
}

//Temporary Data Container class to store objects\data    
public static class StackManager
{
  public static Stack DataStack = new Stack();
}

//This class doesn't require any input to operate
public class OpsA : IHandler
{
  public IHandler Successor {get; set; }
  public void Process()
   {
      //Do some processing, store the result into Stack
      var ProcessedData = DoSomeOperation();
      StackManager.DataStack.Push(ProcessedData);

      if(Successor != null) Successor();            
  }
}

//This class require input data to operate upon
public class OpsB : IHandler
{
  public IHandler Successor {get; set; }
  public void Process()
  {
      //Retrieve the results from the previous Operation
      var InputData =  StackManager.DataStack.Pop();

      //Do some processing, store the result into Stack
      var NewProcessedData = DoMoreProcessing(InputData);      
      StackManager.DataStack.Push(NewProcessedData);

      if(Successor != null) Successor();
  }
}

public class ChainOfResponsibilityPattern
{
  public void Process()
  {
       IHandler ProcessA = new  OpsA();  
       IHandler ProcessB = new  OpsB();

       ProcessA.Successor = ProcessB;
       ProcessA.Process();
  }
}

Пожалуйста, помогите мне найти лучший подход для передачи данных между обработчиками в цепочке.

Ответы [ 3 ]

5 голосов
/ 18 марта 2011

Когда у вас есть цепочка ответственности, это обычно включает в себя один контекст, поэтому хорошим подходом является передача объекта Context.

Одна интересная вещь, которую я хотел бы отметить, касается изменчивости контекста.

Вы можете иметь изменяемый контекст, а затем создать экземпляр объекта контекста, передав его в ProcessorA. ProcessorA может изменить его и установить собственные данные, а затем передать его на ProcessorB. Затем ProcessorB изменяет его еще немного, и, наконец, вызывающая сторона может прочитать контекст.

Если вы хотите повысить безопасность данных и инкапсулировать поведение каждого Processor в качестве черного ящика ввода-вывода, вы можете выбрать неизменный контекстный объект. ProcessorA может получить пустой объект контекста, затем создать его для ProcessorB и вернуть вывод ProcessorB.

4 голосов
/ 18 марта 2011

Было бы гораздо более стандартным добавить аргумент в ваш метод IHandler.Process(), чтобы один объект проходил через всю цепочку, и чтобы каждая запись в цепочке использовала и изменяла переданный объект по мере необходимости. Этот объект может быть вашим стеком, но зависимость от предыдущих записей, помещающих что-либо в стек, все еще делает процессоры очень взаимозависимыми.

С более подробной информацией о том, что вы на самом деле делаете, мы могли бы предложить лучший подход, и, возможно, цепочка ответственности просто не подходит.

1 голос
/ 18 марта 2011

Почему бы просто не передать словарь или даже список?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...