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

March 14, 2009

Find….

Filed under: Programming, c# — Tags: , , , , , — admin @ 1:57 am
In 2.0 when you’re looking for an item within a List<T> object you can do the following…
Lets assume you’re looking for an Task item with a known Id.
[sourcecode language='csharp']
int id = int.Parse(taskList.SelectedValue);
foreach (Task t in AllTasks)
{
    if (t.Id == id)
        return t;
}
[/sourcecode ]
You loop through all the items in the collection and return the first one that matches.
 

 

But in 2.0 you can replace that with the Find method on the List<T> object and smacking in an anonymous/inline delegate ….

 
So the above now becomes.
 
int id = int.Parse(taskList.SelectedValue);
return AllTasks.Find(delegate(Task t) { return t.Id == id; });
 
the Find method takes a single argument which is a predicate delegate and searches through the list for the condition defined by the predicate and returns the first one found.
 
 
..And in 3.5 .. it gets even simpler (in my opinion): 
int id = int.Parse(taskList.SelectedValue);
return AllTasks.Find(x=>x.id==id);
 
Hope this helps!
Thanx

Powered by WordPress