Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Executing Chain of Responsibility variation

I have got a pipeline of tasks which basically is a variation of chain of responsibility pattern.

A task in my pipeline looks as below

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

..and my processor looks like

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

and my concrete implementation looks like this:

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

..and my tasks look like this:

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

T could be different instances, but bound by a generic contract. One of the tasks are about mapping the incoming object into a completely different object and forwarding that instance from there onwards.

Now as you would see, I'm executing all the tasks in the pipeline, I would like to modify this to the following:

  • Input for the Execute method for the next task should be from the previously executed task.
  • If the CanExecute fails for a task then the pipeline should stop processing the tasks.

Can you please help me in getting this. Also would you expect the code to be structured differently for this purpose?

like image 301
Mike Avatar asked Jun 21 '12 17:06

Mike


1 Answers

How about this:

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

         result = individual.Process(result);
     }

     return result;
}

As you have it currently, it is much more like a composite pattern than a chain of responsibility. This change makes it a little bit more CoR-ish. But it is more important to note whether it meets your needs than to use the correct design pattern jargon. :)

like image 149
tallseth Avatar answered Sep 27 '22 16:09

tallseth