0

我正在设计一个框架,并且我有复合对象,这些对象具有异步或同步执行的子对象。对于同步执行的,通常在某个子项完成后,必须在复合对象中运行某种类型的逻辑。

问题是有许多子项,对于每个子项,在每个子项之后可能会进行不同的处理,并且因为我的目标是简单,我将同步项放在队列中,而复合项只会弹出它们一个接一个地运行它们..现在跟踪子项目的最干净的方法是什么,这样我就可以说“在子项目 #2 完成后,获取它返回的数据并执行 xyz()”?

4

3 回答 3

1

命令模式。这听起来像是一个 CompositeCommand,它维护着一个命令列表。每个Command 都有一个execute() 操作,CompositeCommand 的execute 操作遍历命令列表并调用每个Command 的execute。在 CompositeCommand 的 execute() 方法中,您可以在每次迭代后执行 xyz() 的逻辑。

您还提到每个命令可以以不同的方式处理,这可以通过策略来实现。

于 2012-07-11T16:04:05.220 回答
1

如果您的后处理选项数量有限,请考虑类似访客模式。

组合将为可能需要的每种类型的后处理实现一个方法,子项将实现一个方法,该方法采用组合的实例并调用其中一个后处理方法,具体取决于它是哪种子项是。由于您已经在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);
  }
}
于 2012-07-11T16:25:20.193 回答
0

我建议将任何依赖逻辑移到它自己的操作中。

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

这个概念的变化是无穷无尽的。

于 2012-07-12T17:10:41.353 回答