Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 以责任链模式在对象之间传递数据_C#_Design Patterns - Fatal编程技术网

C# 以责任链模式在对象之间传递数据

C# 以责任链模式在对象之间传递数据,c#,design-patterns,C#,Design Patterns,在实施责任链模式时,我遇到了一个难题:如何在链中的对象之间传递数据。链中对象之间传递的数据类型可能因每个对象而异。作为临时修复,我创建了一个包含堆栈的静态类,其中链中的每个对象都可以将结果推送到堆栈中,而链中的下一个对象可以从堆栈中弹出结果。下面是我实现的示例代码 public interface IHandler { IHandler Successor {get; set; } void Process(); } //Temporary Data C

在实施责任链模式时,我遇到了一个难题:如何在链中的对象之间传递数据。链中对象之间传递的数据类型可能因每个对象而异。作为临时修复,我创建了一个包含堆栈的静态类,其中链中的每个对象都可以将结果推送到堆栈中,而链中的下一个对象可以从堆栈中弹出结果。下面是我实现的示例代码

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

请帮助我找到一种更好的方法在链中的处理程序之间传递数据。

为什么不传递一个字典,甚至一个列表?

IHandler.Process()
方法中添加一个参数将更为标准,这样单个对象就可以通过整个链,并让链中的每个条目根据需要使用和修改传递的对象。这个对象可以是您的堆栈,但是依赖于以前的条目将某些内容推到堆栈上,这仍然使得处理器高度相互依赖


有了更多关于您实际正在做的事情的详细信息,我们可能会建议一种更好的方法,这可能是责任链并不合适。

当您有责任链时,这通常涉及一个单一的上下文,因此一个好的方法是传递一个
上下文
对象

我要注意的一件有趣的事情是上下文的易变性

您可以拥有一个可变上下文,然后实例化上下文对象,将其传递给
ProcessorA
ProcessorA
可以修改它并设置自己的数据,然后将其传递给
ProcessorB
。然后
ProcessorB
对其进行更多修改,最后调用者可以读取上下文


如果您希望具有更高的数据安全性,并将每个
处理器的行为封装为输出黑盒的输入,则可以选择不可变上下文对象
ProcessorA
可能会接收到一个空的上下文对象,然后为
ProcessorB
构造一个,并返回
ProcessorB
的输出。

你的意思是使用Dictionary或IList而不是Stack吗?确实,这就是我的意思。当您传递一个列表或字典时,添加/修改数据的顺序并不重要。您实际上想从使用链模式中得到什么?您的每个链接似乎都与之前的链接紧密耦合,这表明您可能也知道您正在调用的具体类型。您是否有多个可以处理相同数据类型的链接?除了第一个链接外,你的所有链接都处理堆栈中的数据吗?这似乎不是正确使用CoR模式的方法,你应该能够更改链的顺序,并且它应该继续工作。我猜责任链在这里是不正确的。@AbrahamJP,你最终在这个场景中做了什么。这是一个有趣的设计问题。你是否使用了一个通用的可变上下文对象来传递不同的阶段?上下文对象是否变得太大?每个阶段如何知道在上下文对象中查找什么?谁负责确保上下文对象被正确填充?向process方法添加参数是一个很好的建议。我试图实现的是,我有一个应用程序,可以执行一些ETL操作,如从文件读取、验证、转换、加载等。这些操作的顺序可能因不同的客户端而异。所以我的计划是为每个操作创建独立的处理对象,并根据需要为每个客户机将其链接在一起。在我的例子中,大约有30多个处理对象。我所说的处理对象是指读取文件、进行服务调用、DB写入操作等。我非常喜欢这种方法。它引入了一定级别的抽象,另外,上下文甚至可以包含上下文中的多个项目,这些项目可能会在CoR中的不同步骤中进行修改。