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中的不同步骤中进行修改。