fuzzelogic Solutions

March 26, 2009

Chain of responsibility

Hi!

In an application I’m currently working on I have a need to process the file. The processing is determined by the type of file it is. Sounds like an ideal condidate for large complicated “if” block…. or chain of responsibility pattern. hmmmm.

COR seems like exactly what I want.. so first we need handlers ( these can handle the file ) then we need to tell each handler the next handler .. then have a means of determining if a handler can actually process the request, if not it passess this to the next handler in the chain.
Initially this is what I ended up with…

IHandler doc= new DocFileHandler();   
IHandler xl= new XLFileHandler();   
IHandler ppt= new PPTFileHandler();     // Setup the chain of responsibility.     doc.SetNextHandler(xl);    
xl.SetNextHandler(ppt);               // Throw the first handler the file request .    
doc.Handle(someFile);

It works, all goes well, but still…. all I want to do is tell the handler if it can’t handle the request to pass it on. There’s only a NEXT handler, not a list, so I used the following…

the interface ..

public interface {
void Handle(T itemToHandle);
bool CanHandle(T item);
}

and another class …

public class ChainedHandlers<T>:IHandler<T>
    {
        private readonly IHandler<T> first;
        private readonly IHandler<T> nextHandler;

        public ChainedHandlers(IHandler<T> first, IHandler<T> nextHandler )
        {
            this.first = first;
            this.nextHandler = nextHandler;
        }

        public void Handle(T itemToHandle)
        {
            if (first.CanHandle(itemToHandle))
                first.Handle(itemToHandle);
            else
            {
                nextHandler.Handle(itemToHandle);
            }
        }

        public bool CanHandle(T item)
        {
            return true;// a fake value ??
        }
    }

then …. as an extension class I created…

static public IHandler<T> add_next_handler <T>(this IHandler<T> first, IHandler<T> nextHandler )

{
 return new ChainedHandlers<T>(first, nextHandler);
 }

So far so good.. so using all this now I can do…

 var  docHandler = new DocHandler();
 docHandler
  .add_next_handler(new XlHandler())
                .add_next_handler(new PPTHandler())
                .Handle(someFile);
 

Points of interest : It’s an example of the Open/Closed Principle.  The behavior of the system can be altered by either adding handlers or changing the order of the handlers in the chain of responsibility without making any further code modifications.

Hope this helps!
Zak

« Newer Posts

Powered by WordPress