2012-06-21 28 views
5

我有一个基本上是责任链模式变化的任务管道。执行责任链变化

我在管道中的任务看起来如下

internal interface IPTask<T> 
{ 
    bool CanExecute(T instance); 
    T Process(T instance); 
} 

..和我的处理器看起来像

internal interface IProcessor<T> 
{ 
    T Execute(T instance); 
} 

和我的具体实施看起来是这样的:

public class Processor<T> : IProcessor<T> 
{ 
    private readonly ITasks<T> tasks; 

    public Processor(ITasks<T> tasks) 
    { 
     this.tasks= tasks; 
    } 

    public T Execute(T instance) 
    { 
     var taskstoExecute = tasks.GetTasks() 
            .Where(task => task.CanExecute(instance)); 

     taskstoExecute.ToList().ForEach(task=>task.Process(instance)); 

     return T; 
    } 
} 

..我的任务如下所示:

internal interface ITasks<T> 
{ 
    IEnumerable<IPTask<T>> GetTasks(); 
} 

T可能是不同的实例,但受通用合同约束。其中一个任务是将传入的对象映射到完全不同的对象并从那里向前转发该实例。

现在,你会看到,我正在执行的所有任务的管道,我想修改这个以下:

  • 输入为Execute方法,接下来的任务应该是从先前执行的任务。
  • 如果某个任务的CanExecute失败,那么管道应停止处理任务。

你能帮我解决这个问题吗?你也希望代码在结构上有不同的结构吗?

回答

3

如何:

public T Execute(T instance) 
{ 
    T result = instance; 
    foreach(var individual in tasks.GetTasks()) 
    { 
     if(!individual.CanExecute()) break; 

     result = individual.Process(result); 
    } 

    return result; 
} 

当你拥有它目前,它更喜欢比的链的复合模式责任。这种变化使得它更加复杂。但更重要的是要注意它是否符合您的需求,而不是使用正确的设计模式术语。 :)

3

在此实现中,CanProcess实际上用于触发将停止该过程的异常。

我添加了第二个实现,名为ExecuteWithPartial,它处理异常,以防止出现您期望的行为。它处理,但如果有错误,它会返回到该点的部分结果。

public class Processor<T> : IProcessor<T> 
{ 
    //... rest of your code 

    public T Execute(T instance) 
    { 
     return this._tasks.GetTasks().Aggregate(instance, (current, task) => InternalExecute(task, current)); 
    } 

    public T ExecuteWithPartial(T instance) 
    { 
     var target = instance; 
     try 
     { 
      foreach (var task in this._tasks.GetTasks()) 
      { 
       target = InternalExecute(task, target); 
      } 
      return target; 
     } 
     catch (CantExecuteException) 
     { 
      return target; 
     } 
    } 


    private static T InternalExecute(IPTask<T> task, T instance) 
    { 
     if (!task.CanExecute(instance)) 
      throw new CantExecuteException(); 
     return task.Process(instance); 
    } 
} 

而新的异常类:

public class CantExecuteException : Exception 
{ 
}