我正在设计一个框架,并且我有复合对象,这些对象具有异步或同步执行的子对象。对于同步执行的,通常在某个子项完成后,必须在复合对象中运行某种类型的逻辑。
问题是有许多子项,对于每个子项,在每个子项之后可能会进行不同的处理,并且因为我的目标是简单,我将同步项放在队列中,而复合项只会弹出它们一个接一个地运行它们..现在跟踪子项目的最干净的方法是什么,这样我就可以说“在子项目 #2 完成后,获取它返回的数据并执行 xyz()”?
我正在设计一个框架,并且我有复合对象,这些对象具有异步或同步执行的子对象。对于同步执行的,通常在某个子项完成后,必须在复合对象中运行某种类型的逻辑。
问题是有许多子项,对于每个子项,在每个子项之后可能会进行不同的处理,并且因为我的目标是简单,我将同步项放在队列中,而复合项只会弹出它们一个接一个地运行它们..现在跟踪子项目的最干净的方法是什么,这样我就可以说“在子项目 #2 完成后,获取它返回的数据并执行 xyz()”?
命令模式。这听起来像是一个 CompositeCommand,它维护着一个命令列表。每个Command 都有一个execute() 操作,CompositeCommand 的execute 操作遍历命令列表并调用每个Command 的execute。在 CompositeCommand 的 execute() 方法中,您可以在每次迭代后执行 xyz() 的逻辑。
您还提到每个命令可以以不同的方式处理,这可以通过策略来实现。
如果您的后处理选项数量有限,请考虑类似访客模式。
组合将为可能需要的每种类型的后处理实现一个方法,子项将实现一个方法,该方法采用组合的实例并调用其中一个后处理方法,具体取决于它是哪种子项是。由于您已经在execute
处理子项目,因此您可以让它们在该方法的末尾调用后处理方法。
一个示例,跳过接口定义:
class CompositeA implements Composite {
public ? process() {
for (Sub subItem : subItems) {
subItem.execute();
subItem.postProcess(this);
}
}
public ? postProcessA(SubA subItem) {
//do something with SubA
}
public ? postProcessB(SubB subItem) {
//do something with SubB
}
}
class CompositeB implements Composite {
public ? process() {
for (Sub subItem : subItems) {
subItem.execute();
subItem.postProcess(this);
}
}
public ? postProcessA(SubA subItem) {
//do something else with SubA
}
public ? postProcessB(SubB subItem) {
//do something else with SubB
}
}
class SubA implements Sub {
public ? execute() {
//doSomething
}
public ? postProcess(Composite composite) {
comp.postProcessA(this);
}
}
class SubB implements Sub {
public ? execute() {
//doSomething
}
public ? postProcess(Composite composite) {
comp.postProcessB(this);
}
}
我建议将任何依赖逻辑移到它自己的操作中。
abstract Operation
{
abstract ? Execute(? arg); // override in subclass to do work
}
abstract PostProcessOperation : Operation
{
Operation _sourceOp;
Operation(Operation sourceOp)
{
_sourceOp = sourceOp;
}
override ? Execute(? arg)
{
? sourceResult = _sourceOp.Execute(arg);
return PostProcess(sourceResult);
}
abstract ? PostProcess(? arg); // override in subclass to do work with results of the source op Execute
}
然后,例如,将后处理控制台日志记录添加到您可以执行以下操作的操作:
class ResultLogOp : PostProcessOperation
{
override ? PostProcess(? arg)
{
Console.Writeline(arg.ToString());
}
}
为了进一步举例,假设您有一个文件删除操作,并且您希望通过记录其成功来对其进行后处理:
DeleteFileOp deleteFile = DeleteFileOp(fileToDelete);
ResultLogOp loggedDeleteFile = new ResultLogOp(deleteFile);
operations.Enque(loggedDeleteFile);
或者,如果您的用法不同,也许您的容器类可以包装某些关键操作,因为它们是根据它们的类型添加的:
void Add(Operation child)
{
if (child is ImportantType)
{
_operations.Add(new ResultLogOp(child); // add logging transparently on the fly
}
}
这个概念的变化是无穷无尽的。