Sony Arouje

a programmer's log

Chain of Responsibility pattern with Dependency Injection

with 11 comments

Recently one of my friend asked me for a suggestion while preparing for an interview. The problem was, to find what kind of triangle by passing three values, whether it’s Equilateral or Isosceles, etc. He wanted to implement a scalable approach, that means adding a new type of triangle with minimal code change. First approach came to my mind is Iterator pattern, I ruled out that pattern immediately as it needs code change, if we want to add a new triangle. Next approach came to my mind is Chain of Responsibility, if we combine this pattern with Dependency Injection then will have room for scalability.

For demonstration I used Castle Windsor Inversion of Control container. I can add new triangles with minimal or no code change if we use IOC containers. We can add new triangles just by adding new component to the configuration file.

What is Chain of Responsibility?  It’s like a quiz competition, if one team is not able to answer the question then pass it to another team. You can find more about Chain of Responsibility here . One main advantage of this approach is low coupling and orthogonal.

I used Chain of Responsibility to solve the Triangle problem. I have several type of Triangle class derived from ITriangle interface and stitched together using Castle Windsor. The values will passed to the first Triangle instance, if the first triangle instance can handle it, then return the result other wise pass the values to the next instance in the chain.

Let’s see the implementation.

public interface ITriangle
{
    string Execute(int x, int y, int z);
    void Add(ITriangle triangle);
}

 

Different Triangle Implementation

public class EquilateralTriangle:ITriangle
{
    private ITriangle _triangle=null;
    public EquilateralTriangle(ITriangle nextTriangle)
    {
        _triangle = nextTriangle;
    }
    public string Execute(int x, int y, int z)
    {
        int average = (x + y + z) / 3;
        if (average == x)
            return this.ToString();
        else
        {
            if(_triangle!=null)
                return _triangle.Execute(x, y, z);
        }

        return string.Empty;
    }

    public void Add(ITriangle triangle)
    {
        _triangle = triangle;
    }

    public override string ToString()
    {
        return "Equilateral Triangle";
    }
}

 

public class IsoscelesTriangle : ITriangle
{
    public IsoscelesTriangle (ITriangle nextTriangle)
    {
        _triangle = nextTriangle;
    }
    public IsoscelesTriangle() { }
    private ITriangle _triangle = null;
    public string Execute(int x, int y, int z)
    {
        int average1 = (x + y) / 2;
        int average2 = (y + z) / 2;
        int average3 = (x + z) / 2;
        if (average1 == x || average2 == y || average3 == z)
            return this.ToString();
        else
        {
            if (_triangle != null)
                return _triangle.Execute(x,y,z);
        }
        return string.Empty;
    }

    public void Add(ITriangle triangle)
    {
        _triangle = triangle;
    }
    public override string ToString()
    {
        return "Isosceles Triangle";
    }
}

 

So now I have two different type of Triangles. Both implementation check the values and if it satisfies then return the name other wise pass it to the chain.

Let’s see how can we call this

ITriangle isoscelesTriangle = new IsoscelesTriangle();
ITriangle head = new EquilateralTriangle(isoscelesTriangle);
Console.WriteLine(head.Execute(10,10,10));
Console.WriteLine(head.Execute(11,11,20));

 

The output will be

Equilateral Triangle
Isosceles Triangle

Here is one problem, if I want to add a new Triangle then I have to modify the code here. So how to make it scalable with no code change. Let’s see how we can scale it using an IOC Container. As I told earlier I am going to use Castle Windsor here.

We can use Fluent API or XML configuration to configure our components. Here I used XML for configuration. Let’s go through xml configuration file

<configuration>
  <components>
    <component id="IsoscelesTriangle"
      service="Triangles.IsoscelesTriangle, Triangles"
      type="Triangles.IsoscelesTriangle, Triangles">     
    </component>    
    <component id="Equilateral"
          service="Triangles.ITriangle, Triangles"
          type="Triangles.EquilateralTriangle, Triangles">
      <parameters>
        <nextTriangle>${IsoscelesTriangle}</nextTriangle>
      </parameters>
    </component>
  </components>
</configuration>

 

Have a look at the component with id Equilateral, I mentioned the interface and class that implements it. Also you can notice some thing called parameters, their I pass the constructor’s parameter. Here I directed castle to pass the instance of IsoscelesTriangle.

In Component IsoscelesTriangle we dont have any parameters, in this scenario it uses the default constructor.

Next step, we need to pass this configuration file to castle. Bellow code explains it.

public static class Ioc
{
    private static IWindsorContainer _container = null;
    public static T Resolve<T>() where T : class
    {
        InitializeWindsorContainer();
        return _container.Resolve<T>();
    }

    private static void InitializeWindsorContainer()
    {
        try
        {
            if (_container == null)
            {
                StringBuilder basePath = new StringBuilder(AppDomain.CurrentDomain.BaseDirectory);
                basePath.Append(@"IocConfiguration.xml");
                _container = new WindsorContainer(new XmlInterpreter(basePath.ToString()));
            }
        }
        catch (Exception ex)
        {
            throw;
        }
    }
}

Now we completed our IOC and configuration. Let’s see how I find the triangle now.

ITriangle head = Ioc.Resolve<ITriangle>();
Console.WriteLine(head.Execute(10,10,10));
Console.WriteLine(head.Execute(11,11,20));

 

Previously I created Isosceles Triangle instance then create Equilateral instance and pass Isosceles instance through constructor. In the above scenario, castle will create Equilateral instance by creating and passing Isosceles instance. So we are completely freed of creating the chains.

How can we add a new traingle? It’s very simple, first create a new triangle class derived from ITriangle as shown below.

public class XTriangle:ITriangle
{
    ITriangle _triangle;
    public XTriangle(){}

    public XTriangle(ITriangle nextTriangle)
    {
        _triangle = nextTriangle;
    }

    public string Execute(int x, int y, int z)
    {
        if (x > y)
        {
            return this.ToString();
        }
        else
        {
            if (this._triangle != null)
                return _triangle.Execute(x, y, z);
        }
        return null;
    }

    public void Add(ITriangle triangle)
    {
        throw new NotImplementedException();
    }
}

 

I need to plug this new Triangle to the chain, it’s as simple as modifying the configuration file as shown below.

Note: There is no triangle called XTriangle, just for demo I created a class.

<configuration>
  <components>
    <component id="XTriangle"
    service="Triangles.XTriangle, Triangles"
    type="Triangles.XTriangle, Triangles">
    </component>

    <component id="IsoscelesTriangle"
      service="Triangles.IsoscelesTriangle, Triangles"
      type="Triangles.IsoscelesTriangle, Triangles">
      <parameters>
        <nextTriangle>${XTriangle}</nextTriangle>
      </parameters>      
    </component>
    
    <component id="Equilateral"
          service="Triangles.ITriangle, Triangles"
          type="Triangles.EquilateralTriangle, Triangles">
      <parameters>
        <nextTriangle>${IsoscelesTriangle}</nextTriangle>
      </parameters>
    </component>
  </components>
</configuration>

I made some changes and I marked those changes in Bold Italics. Let’s execute the project once again. As per the configuration the new XTriangle will get added to Isocles Triangle. Now the chain look like

Equilateral Triangle->Isosceles Triangle->XTriangle->[END OF CHAIN]

ITriangle head = Ioc.Resolve<ITriangle>();
Console.WriteLine(head.Execute(10,10,10));
Console.WriteLine(head.Execute(11,11,20));
Console.WriteLine(head.Execute(20, 3, 10));

 

The out put will be

Equilateral Triangle
Isosceles Triangle
Triangles.XTriangle
 

We added a new triangle to the chain with little code change.

Summary

With a mix of patterns we can build a scalable, low coupled system that can maintain very easily. Happy coding…

 

Download the Code

Advertisement

Written by Sony Arouje

April 6, 2011 at 4:32 pm

11 Responses

Subscribe to comments with RSS.

  1. Thanks, it’s usefull

    autobazar

    April 8, 2011 at 5:29 pm

  2. I want to start blogging too what do you think, which blog cms is good for noob?

    tabletki na odchudzanie

    April 10, 2011 at 2:16 pm

  3. Thanks – where is article source?

    site

    April 15, 2011 at 6:18 pm

  4. Excellent idea and simple solution and simple example.

    thanks for great presentation

    Justin Mathew

    April 17, 2011 at 3:52 am

  5. I’m happy to tell you that I am the freshest fellow member in here and as i look forward to talking with all of you within here soon.

    faxySyday

    April 21, 2011 at 6:27 am

  6. Nice one Sony, simple and effective explanation.

    Anonymous

    November 23, 2011 at 12:25 pm


Leave a Reply to faxySyday Cancel reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: