2012-06-21 9 views
5

私は基本的に責任パターンのチェーンのバリエーションですタスクのパイプラインを持っている。実行チェーンの責任のバリエーション

私のパイプラインでの作業は、

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

以下のようになります..and私のプロセッサが

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は異なるインスタンスでも構いませんが、汎用契約で結ばれます。タスクの1つは、着信オブジェクトをまったく別のオブジェクトにマッピングし、そこからそのインスタンスを転送することです。あなたが見るであろうよう

は今、私は次のようにこれを変更したいと思い、パイプライン内のすべてのタスクを実行している:次のタスクのための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; 
} 

、それははるかのチェーンよりも合成パターンのようです責任。この変更により、CoR-ishが少し増えます。しかし、正しいデザインパターンの専門用語を使用するよりも、ニーズを満たしているかどうかを確認することが重要です。 :)

3

この実装では、CanProcessが実際にプロセスを停止する例外をトリガするために使用されます。

予期した動作である場合に備えて、例外を処理する第2の実装である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 
{ 
} 
関連する問題