Object Composition Using Chain of Responsibility Design Pattern

by Zoran Horvat

Introduction

Chain of Responsibility is the first behavioral pattern explained in the Gang of Four book on design patterns. Its intention is given as follows:

            
"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."

Gama et al., Design Patterns - Elements of Reusable Object-Oriented Software
                
    

This explanation is based on a notion of a request, or a message, which is passed to an object. The object is then responsible to execute the request. However, the way in which the request is executed may depend on the situation. We don't want to fix the implementation because a different situation would then require completely new implementation.

An Example

In practice, chain of responsibility is applicable when a certain method can be implemented in different ways. Then we are letting more than one object to analyze the call to the method and decide whether to handle it or to pass the call further down the chain.

But in this article I will analyze one slightly more complicated case – when there are multiple methods that can be called and the object needs to decide how to handle each of the calls. The trick is in the pattern's name itself: Chain of Responsibility. Not chain of responsibilities, but only a single responsibility. This pattern solves the problem of distributing one single responsibility among multiple objects.

Now what would it take to distribute multiple responsibilities across multiple objects that form a single object graph, but in such a way that decisions regarding the distribution of calls becomes the single responsibility of a class? This may sound confusing at first. To make it easier to grasp, let's take one non-trivial example in which responsibilities are not divided in the best possible way.

Suppose that we have a program that displays members of a family - dad, mom, a boy and his dog.

A family

What could we do with this model?

For example, dad might grow beard. On the other hand, mommy would not be happy to grow a beard. The boy is still too young to do so. And the dog... well, dogs have no such a concept as beard.

Next, they could all be happy, including the dog. Note that happiness is exhibited in people through laughing, while the dog has quite a different manifestation, which includes tail waving and fawning.

Next behavior that we might be interested in is growing hair. Dad might think about the idea, but he's bold and ultimately unable to grow anything on top of his head. Mom on the other hand would be quite happy to grow hair. The boy could grow hair but social stigma at his school class doesn't let him do that, so forget about it. And the dog is supposedly a short-haired one and couldn't really grow its hair much longer.

A family

Bottom line is that different kinds of behaviors are implemented by different members of this family.

Let's first formalize the behaviors in form of abstract interfaces and concrete classes that implement them.

Family implementing interfaces

This diagram indicates that every member of the family is implemented as a different class. This is primarily due to their distinct behaviors. The only similarity could be found between the boy and the dog, but I'm not going to make them the same class. Mom and dad are obviously distinct classes, looking at their distinguished abilities to grow different kinds of hair.

Here is the implementation of all these interfaces and classes.

interface IBearded
{
    void GrowBeard();
}

interface IEmotional
{
    void BeHappy();
}

interface IHairy
{
    void GrowHair();
}

class Dad: IBearded, IEmotional
{

    public void GrowBeard()
    {
        Console.WriteLine("Dad grows beard.");
    }

    public void BeHappy()
    {
        Console.WriteLine("Dad laughs.");
    }

}

class Mom : IHairy, IEmotional
{
    public void GrowHair()
    {
        Console.WriteLine("Mom grows hair.");
    }

    public void BeHappy()
    {
        Console.WriteLine("Mom laughs.");
    }
}

class Boy : IEmotional
{
    public void BeHappy()
    {
        Console.WriteLine("Boy laughs.");
    }
}

class Dog : IEmotional
{
    public void BeHappy()
    {
        Console.WriteLine("Dog waves its tail.");
    }
}

These are the implementations of all four classes that would form a family. I could finally use them as part of another class which is meaningful for me, a class that represents the family:

class Family
{

    private readonly IEnumerable<object> members;

    public Family(IEnumerable<object> members)
    {
        this.members = members;
    }

    public void WinterBegins()
    {
        Console.WriteLine("Winter just came...");
        foreach (object obj in members)
        {
            if (obj is IHairy)
            {
                Console.Write("{0}: ", obj.GetType().Name);
                ((IHairy)obj).GrowHair();
            }
            if (obj is IBearded)
            {
                Console.Write("{0}: ", obj.GetType().Name);
                ((IBearded)obj).GrowBeard();
            }
        }
        Console.WriteLine(new string('-', 20));
    }

    public void SummerComes()
    {
        Console.WriteLine("Summer is here...");
        foreach (object obj in members)
        {
            if (obj is IEmotional)
            {
                Console.Write("{0}: ", obj.GetType().Name);
                ((IEmotional)obj).BeHappy();
            }
        }
        Console.WriteLine(new string('-', 20));
    }
}

This class lets me ignite changes in the family which happen whenever a winter or summer begins. Basically, this family is quiet on winters and loud on summers. Here is the demonstration:

static void Main()
{
    Family family =
        new Family(
            new object[] { new Dad(), new Mom(), new Boy(), new Dog() });

    family.WinterBegins();
    family.SummerComes();
    Console.ReadLine();

}

This is the case of a family which consists of four members, and we can let that family behave in their characteristic manner when seasons change. This is the program output:

            
Winter just came...
Dad: beard grows
Mom: hair gets long
--------------------
Summer is here...
Dad: hoho
Mom: hihi
Boy: haha
Dog: tail waving
--------------------
                
    

As you can see, all objects have fulfilled their purpose. Each interface implementation was invoked in just right time. Additionally, every object has fulfilled its purpose in a specific way, which is distinct from any other object.

But the price of achieving this success is not that small. First of all, I had to code a separate class for each combination of behaviors. Suppose that we have a granddad added to the family. He could grow hair and laugh, but also grow beard, which makes him distinct from any other family member. I could add a grouchy uncle who can grow beard and hair but never shows emotions. Would each of these combinations require a new class?

And what about adding more behaviors? For example building ship models, which could be the specialty of dad and the boy. Mom might not like building models, and the dog would not get the point of the activity anyway. Does it mean that now I have to extend two classes to add new ability to them? And what about the Single Responsibility Principle when every class potentially implements the whole bunch of interfaces?

Furthermore, let's take a look at the Family class. In its constructor, this class expects a collection of objects. Why objects? Why not some base class, or some common interface? Well, because these four classes that represent family members have nothing in common. There is no common behavior for them. There is no base class for all of them and no abstract interface that all of them would implement.

Finally, implementation of actual methods in the Family class depends on actual types of contained objects. Here lies one unfortunate attempt of getting through interface definitions to call particular implementation:

if (obj is IHairy)
    ((IHairy)obj).GrowHair();

Conditional downcasting. I suppose that none of us programmers is happy to see a piece of code like this.

From this point onwards, I will try to redesign these family classes so that each of them becomes focused on a single responsibility. By doing so, I hope for getting a much better design which exhibits at least one benefit: it will be easier to extend with new features.

Replacing Class Inheritance with Object Composition

I plan to provide specific implementations of interfaces and then to compose objects by selecting a subset of concrete implementations. Here is the idea from which I could start:

Composition of objects

I want all concrete classes to be just composed of elements that actually implement desired interfaces. In that way, it would be easy to change behavior of one concrete class by simply submitting a different interface implementation. On a related note, behavior encapsulated in concrete interface implementation would not be repeated in any of the classes that depend on it.

But this is just a half of the story. Another half is the Family class. In order to let this class use features of Dad, Mom and other classes, these classes still have to implement abstract interfaces such as IHairy or IEmotional. Implementation would be dummy, of course - each class would just delegate the call to its contained component - but all the methods proposed by interfaces would still be there. And Family class would still perform a conditional downcast to access any of these methods.

Bottom line is that this is not a good solution. It could be a step in the right direction, but not a complete solution in its own right.

Instead of exposing all interfaces transitively in the composed object, I could let the composed object expose its contained objects instead. For example, family members could all be represented by instances of one class:

Generic composition of objects

In this case, any family member can be created as a combination of its behaviors. Generic method As is there to let the callers get grasp of the contained component which encapsulates desired behavior.

With this latest modification, I am finally ready to tackle the problem by chaining concrete interface implementations under the FamilyMember object.

Using Chain of Responsibility to Implement Object Composition

Here is the final idea. Let each of the components tell if it meets the requested type. To do so, I want to organize components into a chain, and the fact that each link in the chain only attempts to handle a single kind of request makes it a chain of responsibility.

Here is the new class which makes all this possible:

class ChainElement
{

    private readonly ChainElement next;

    public ChainElement(ChainElement next)
    {
        this.next = next;
    }

    public virtual T As<T>(T defaultValue) where T: class
    {

        if (this is T)
            return this as T;

        if (this.next != null)
            return this.next.As<T>(defaultValue);

        return defaultValue;

    }

}

Each object of this class represents one link in the chain of responsibility. And the responsibility of the link is to provide the generic As method implementation in order to test whether it implements the desired type. Default implementation of the As method just tests type of the current object. If it meets the requested type, method just returns current object.

The As method is virtual. Any particular component is free to provide a more detailed implementation if needed. With behaviors regarding hair, beard and laughter we don't need anything more advanced than this implementation. Therefore, here are the simple implementations of all behaviors:

class Bearded : ChainElement, IBearded
{

    private readonly string owner;

    public Bearded(string owner, ChainElement next)
        : base(next)
    {
        this.owner = owner;
    }

    public void GrowBeard()
    {
        Console.WriteLine("{0}: beard grows", this.owner);
    }
}

class Emotional : ChainElement, IEmotional
{

    private readonly string owner;
    private readonly string laughingSound;

    public Emotional(string owner, string laughingSound, ChainElement next)
        : base(next)
    {
        this.owner = owner;
        this.laughingSound = laughingSound;
    }

    public void BeHappy()
    {
        Console.WriteLine("{0}: {1}", this.owner, this.laughingSound);
    }
}

class Hairy : ChainElement, IHairy
{

    private readonly string owner;

    public Hairy(string owner, ChainElement next)
        : base(next)
    {
        this.owner = owner;
    }

    public void GrowHair()
    {
        Console.WriteLine("{0}: hair gets long", this.owner);
    }
}

Finally, here is the class that keeps the whole chain of responsibility as its subordinated object graph:

class FamilyMember
{

    readonly ChainElement components;

    public FamilyMember(ChainElement components)
    {
        this.components = components;
    }

    public T As<T>(T defaultValue) where T : class
    {
        return this.components.As<T>(defaultValue);
    }
}

FamilyMember class must still provide implementation for the As method. It still has to delegate calls to contained components, but this time it is only a single method. FamilyMember needs only implement one member that will provide the caller access all interfaces that are implemented under its hood. This is a huge improvement over a number of distinct interfaces that the class would have to implement, each carrying at least one method that asks for a concrete implementation.

The As method expects default result that it will return in case that none of the links responded to the request. To make use of this parameter, I will provide Null Object pattern implementations for all three interfaces:

class NullBearded : IBearded
{

    private static IBearded instance;

    public static IBearded Instance
    {
        get
        {
            if (instance == null)
                instance = new NullBearded();
            return instance;
        }
    }

    public void GrowBeard() { }

}

class NullEmotional : IEmotional
{

    private static IEmotional instance;

    public static IEmotional Instance
    {
        get
        {
            if (instance == null)
                instance = new NullEmotional();
            return instance;
        }
    }

    public void BeHappy() { }

}

class NullHairy : IHairy
{

    private static IHairy instance;

    public static IHairy Instance
    {
        get
        {
            if (instance == null)
                instance = new NullHairy();
            return instance;
        }
    }

    public void GrowHair() { }

}

These classes are applications of Null Object design pattern and Singleton design pattern. Their sole purpose is to provide concrete implementation of all three abstract interfaces such that nothing happens when any of the methods is invoked. I will now modify the Family class and then it will become quite apparent how convenient all the classes developed this far have become:

class Family
{

    private readonly IEnumerable<FamilyMember> members;

    public Family(IEnumerable<FamilyMember> members)
    {
        this.members = members;
    }

    public void WinterBegins()
    {
        Console.WriteLine("Winter just came...");
        foreach (FamilyMember member in members)
        {
            member.As<IHairy>(NullHairy.Instance).GrowHair();
            member.As<IBearded>(NullBearded.Instance).GrowBeard();
        }
        Console.WriteLine(new string('-', 20));
    }

    public void SummerComes()
    {
        Console.WriteLine("Summer is here...");
        foreach (FamilyMember member in members)
        {
            member.As<IEmotional>(NullEmotional.Instance).BeHappy();
        }
        Console.WriteLine(new string('-', 20));
    }
}

And that is all. Just let the caller provide a (preferably non-null) default value and that value will be returned if all other attempts fail. This time, there are no more conditional statements. There are no downcasts, explicit or compiler-provided. Every action is executed unconditionally. Null Object is used to fill in the blanks and protect the caller from NullReferenceException.

Composing the family is now a little bit different. Instead of having each family member being an instance of one hard-coded class, now I’m building each family member as a composed object. Here is the modified method which consumes these classes:

static void Main()
{
    FamilyMember dad =
        new FamilyMember(
            new Bearded("Dad",
                new Emotional("Dad", "hoho", null)));
    FamilyMember mom =
        new FamilyMember(
            new Hairy("Mom",
                new Emotional("Mom", "hihi", null)));
    FamilyMember boy =
        new FamilyMember(
            new Emotional("Boy", "haha", null));
    FamilyMember dog =
        new FamilyMember(
            new Emotional("Dog", "tail waving", null));
    FamilyMember uncle =
        new FamilyMember(
            new Bearded("Uncle",
                new Hairy("Uncle", null)));

    Family family = new Family(new FamilyMember[] { dad, mom, boy, dog, uncle });

    family.WinterBegins();
    family.SummerComes();
    Console.ReadLine();

}

Note that I have even used the opportunity to add a grouchy uncle to the family. He is the guy who could easily grow hair or beard, but would never laugh. That is unique set of behaviors in this family – no one else behaves like that. But I still didn’t have to define a new class for that purpose. I have just composed the uncle from known behaviors and made another unique combination in a dedicated object. This object behaves the same as a class which implements IHairy and IBearded interfaces and nothing else, only it did not require a new class to be coded.

            
Winter just came...
Dad: beard grows
Mom: hair gets long
Uncle: hair gets long
Uncle: beard grows
--------------------
Summer is here...
Dad: hoho
Mom: hihi
Boy: haha
Dog: tail waving
--------------------
                
    

Finally, here is the class diagram that corresponds to these final classes.

Chain of Responsibility applied

Classes are finally well separated. Family contains a collection of family members. Each family member points to the chain of its concrete behaviors. Each behavior is isolated from any other and encapsulated in its own class.

Summary

In this article we have seen one possible way of separating responsibilities across a number of classes. The idea is, as usual, that each class performs only one responsibility. But in order to put that idea in motion, we had to add one more class (FamilyMember in the example). This class also has only one responsibility, and that is to let other classes expose themselves when particular type is required for the upcoming operation.

I find this organization preferable over classical inheritance scheme. Benefits of object composition are significant and the way in which objects raise hands when asked for their type is easier to control than downcast and type checking.


If you wish to learn more, please watch my latest video courses

About

Zoran Horvat

Zoran Horvat is the Principal Consultant at Coding Helmet, speaker and author of 100+ articles, and independent trainer on .NET technology stack. He can often be found speaking at conferences and user groups, promoting object-oriented and functional development style and clean coding practices and techniques that improve longevity of complex business applications.

  1. Pluralsight
  2. Udemy
  3. Twitter
  4. YouTube
  5. LinkedIn
  6. GitHub