Design Patterns Series 6 - Chain of Responsibility Pattern

In previous post we discovered one of design patterns that keep your object  know when something has happened and passing a notification to an observer, Observer Pattern, this post will explore another one.

Chain Of Responsibility Pattern
like observer pattern it lets you notify objects of change, but this time, the objects are connected in a chain, in series. The notification goes from one object to the next until an object is found that can handle the notification.

This pattern is all about connecting objects in a chain of notification; as a notification travels down the chain, it is handled by the first object that is set up to deal with the particular notification.

This pattern should "Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it."

You use this pattern when not all your observers are created equal. In other words, if you want to process your notification using hierarchical chain of objects, this is your pattern.

Consider we have three layers in our system, UI layer, business layer, and database layer. When any event occur, the notification should be handled so UI layer will try to handle the notification, if UI layer failed, it will pass the notification to next layer, business layer, to handle it. Again if business layer failed to handle the notification it will be travelled to database layer to handle it.

To keep control over the objects in your chain, make them all implement the same interface that we named it IHelp. with one method(Notify()) that will print out which layer handled the notification.
public interface IHelp
{
     public void Notify(String layer);
}
To chain your objects you can pass to each object's constructor the next object in the chain. We will create three classes one for each layer and each class will implement IHelp interface.
public class UILayer : IHelp
{
    private const String Iamlayer = "UI";
    private IHelp nextObject;

    public UILayer(IHelp nextObject)
    {
        this.nextObject = nextObject;
    }
    public void Notify(String layer)
    {
        if(Iamlayer == layer)
        {
            Console.WriteLine("This Notification From UI Layer");
        }
        else
        {
            this.nextObject.Notify(layer);
        }
    }
}
Write another class but for business layer.
public class BusinessLayer : IHelp
{
    private const String Iamlayer= "Business";
    private IHelp nextObject;

    public BusinessLayer(IHelp nextObject)
    {
        this.nextObject = nextObject;
    }
    public void Notify(String layer)
    {
        if(Iamlayer == layer)
        {
            Console.WriteLine("This Notification From Business Layer");
        }
        else
        {
            this.nextObject.Notify(layer);
        }
    }
}
Write the last class for database layer but note this will be the default object that will handle any notification come.
public class DatabaseLayer : IHelp
{
    public DatabaseLayer()
    {
    }
    public void Notify(String layer)
    {
        Console.WriteLine("This Notification From Database Layer, which is the default");
    }
}
Now lets see how the chain of responsibilities pattern that we just implemented works. We will write a sample test and check its output to see if we wrote the pattern correctly or what. We will create an object from each class and call Notify() method of first layer (UI).
DatabaseLayer db= new DatabaseLayer();
BusinessLayer business = new BusinessLayer(db);
UILayer ui = new UILayer(business);

ui.Notify("database");
ui.Notify("UI");
ui.Notify("Business");
That will print out the following result
This Notification From Database Layer, which is the default
This Notification From UI Layer
This Notification From Business Layer
If you want to handle notifications in a loosely coupled way, but also have a definite chain of command in mind, this is the pattern for you.

you can download the full source code here

Comments

Popular posts from this blog

Android : How to change progress bar color at runtime programmatically?

How to fire RowCommand event of nested GridView?

ASP.Net MVC : Conditional Validation using ValidationAttribute