The GOF "Chain of Responsibility" Design Pattern

The Chain of Responsibility pattern is used to pass responsibility for handling a call to another class. This article gives a basic overview of the pattern.

 

Part 1. Chain of Responsibility Pattern Overview

 

Image1.gif

 

In essence, the Chain of Responsibility pattern is having a list of handlers for a command, which could be implemented as a method call or an actual GOF "Command" pattern class. When a handler receives the command, it either executes it or passes it on to the next handler in the list.

 

This could be used in many scenarios where there are multiple handlers for a command. For example, I am currently working on a project where the state of my objects are being persisted in a SQL database and, at the same time, users can choose to save some of theses objects persisted locally (with binary serialization). So when I am looking for a particular object, the lookup command first searches the shared SQL data store handler and then the command is passed to a local file serialization handler.

 

This pattern is also great for creating redundant systems for reliability. If your main database server temporarily goes offline or gets bogged down and is unable to handle requests, commands could be passed to another handler which would then cache the changes and update the database when it is back online.

 

Part 2. Framework Code.

 

For this sample, our command will be a PhoneCall class with one method "Converse()" which is our command.

 

Image2.gif 

class PhoneCall

{

    public PhoneCall(Person caller)

    {

        m_caller = caller;

    }

 

    private Person m_caller;

 

    public void Converse()

    {

     Console.WriteLine(string.Format("Hello. This is {0} with an important message."

     m_caller.Name));

    }
}

     

And the command handler will be a person.

 

Image3.gif 

 

class Person

{

    public Person(string name)

    {

        m_name = name;

    }

 

    private string m_name;

    private Person m_backupPickerUpper;

 

    public string Name

    {

        get { return m_name; }

        set { m_name = value; }

    }

 

    internal Person BackupPickerUpper

    {

        get { return m_backupPickerUpper; }

        set { m_backupPickerUpper = value; }

    }

 

    public void Pickup(PhoneCall call)

    {

        if (null != m_backupPickerUpper) // pass it on

        {

        Console.WriteLine(string.Format("{0}: Hey {1}! Pick up the phone!",

             this.m_name, m_backupPickerUpper.Name)); 

             // this is where the chain-o-responsibility is executed

             m_backupPickerUpper.Pickup(call);

        }

        else // pick it up

        {

        Console.WriteLine(string.Format("{0}: Hello?", this.m_name)); 

             // this is where it is finally handled (the call is answered)

             call.Converse();

        }

    }
}

   

The Person class has a handler method called "Pickup()" which will be used to process the incoming message (the phone call). If there is a backup handler person, the PhoneCall will be passed to the backup person, otherwise, it will be handled through calling "Converse()" on the PhoneCall object (no one seems to like picking up the phone these days... for me it is usually the video rental store telling me my rentals are past due). This is a basic implementation of the Chain of Responsibility command pattern because the call is getting passed to different handlers (people) in a chain. It will make more sense once we get to the implementing code later.

 

Part 3. Implementation Code.

 

This is how we would implement our chain of responsibility:

 

class Program

{

    static void Main(string[] args)

    {

        Person father = new Person("Father");

        Person mother = new Person("Mother");

        Person son = new Person("Son");

        Person daughter = new Person("Daughter"); 

        father.BackupPickerUpper = mother;

        mother.BackupPickerUpper = son;

        son.BackupPickerUpper = daughter; 

        Person automatedCaller = new Person("ACME Movie Rentals"); 

        PhoneCall call = new PhoneCall(automatedCaller);

        father.Pickup(call); 

        Console.ReadLine();

    }

}

 

And this would be re result:

 

Father: Hey Mother! Pick up the phone!

Mother: Hey Son! Pick up the phone!

Son: Hey Daughter! Pick up the phone!

Daughter: Hello?

Hello. This is ACME Movie Rentals with an important message.

 

Conclusion.

 

The Chain of Responsibility pattern is useful in many situations and there are many ways to implement this pattern. The route you take really depends on the problem at hand. In this sample I tried to keep it as simple as possible to avoid confusion. Hopefully this article gave you a basic understanding of how this pattern works from functional perspective.

 

Until next time,

Happy Coding

Up Next
    Ebook Download
    View all
    Learn
    View all