Using the Chain of Responsibility Pattern

It’ll never be the most commonly used pattern in your design toolbox, but I’ve occasionally had good results using a “Chain of Responsibility” (CoR) pattern to organize wildly variable logic.  Most importantly, my team recently used the pattern a couple of times in some code that’s likely to be supported by another group.  It’s likely that I’ll need to explain the “Chain of Responsibility” pattern to another developer, so here’s my practice run.


 


The original Gang of Four definition of CoR is:


 


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. There is a potentially variable number of “handler” objects and a stream of requests that must be handled. Need to efficiently process the requests without hard-wiring handler relationships and precedence, or request-to-handler mappings.


 


One of the most common pattern usages is to use a series of Strategy classes to handle different types of requests, with some sort of Factory pattern to obtain the proper handler.  In other cases the logic to select the proper Strategy class becomes much more complex than simply running one property of the request through a case statement.  That’s when you might reach for the Chain of Responsibility pattern.  In the CoR pattern each handler contains the logic to test for its applicability to a request.  If it can’t handle the request it’ll send the request to the next handler in the chain.  The original client is completely unaware of the handler chaining.


 


Here’s a real world scenario taken from a shipping system I prototyped several years ago (but didn’t get to build).  Let’s say your company takes orders electronically from either the web or some sort of web service.  The steps to complete and handle an order vary widely based on the customer, size of order, destination, and a host of other things.  The business logic changes rapidly as special cases crop up and disappear.  Let’s say that we have these contrived, fictional cases:


 



  1. Orders to the European Community require a different set of value added tax calculations and we do international shipping through a different set of carriers

  2. Large bulk orders are handled separately within the warehouse and might go to different shipping carriers

  3. Most Favored Customer.  Your largest customer has special requirements for shipping and tracking, and they’re gonna get what they want.  “Thank you sir, may I have another?”  Minor geek points for nailing the movie and actor.

  4. All other domestic and international orders are handled in a generic manner

 


First off, we’ve got an Order class and an abstract OrderHandler class that for the “Chain of Responsibility” handlers.  They look like the following:


 


      public class Order


      {


            private string _countryCode;


            private double _orderAmount;


            private double _customer;


 


            public string CountryCode


            {


                  get { return _countryCode; }


                  set { _countryCode = value; }


            }


 


            public double OrderAmount


            {


                  get { return _orderAmount; }


                  set { _orderAmount = value; }


            }


 


            public double Customer


            {


                  get { return _customer; }


                  set { _customer = value; }


            }


      }


 


      public abstract class OrderHandler


      {


            private OrderHandler _nextHandler;


 


            // Entry point


            public void ProcessOrder(Order order)


            {


                  if (this.CanHandle(order))


                  {


                        this.handleRequest(order);


                  }


                  else


                  {


                        _nextHandler.ProcessOrder(order);


                  }


            }


 


            // Determines if this OrderHandler can handle the order


            public abstract bool CanHandle(Order order);


 


            // Performs the specific actions for the type of order


            protected abstract void handleRequest(Order order);


 


            // Take in an OrderHandler and put it at the very end of the Linked List


            public void AppendSibling(OrderHandler lastHandler)


            {


                  if (_nextHandler == null)


                  {


                        _nextHandler = lastHandler;


                  }


                  else


                  {


                        _nextHandler.AppendSibling(lastHandler);


                  }


            }


      }


 


The OrderHandler implements a linked list structure.  When the ProcessOrder() method is called, an OrderHandler uses its CanHandle() method to determine if it can handle the Order.  If it can handle the Order, it calls its handleRequest() method to process the order and returns.  Otherwise the OrderHandler passes the Order to the next OrderHandler sibling in the chain until some handler can process the Order.  An obvious warning is required here, there needs to be some sort of last resort, default handler at the end of the chain.  So now we can create the specific handlers for the cases we outlined above and the OrderService itself.


 


      public class MostFavoredCompanyHandler : OrderHandler{…}


      public class EuropeanOrderHandler : OrderHandler{…}


      public class LargeOrderHandler : OrderHandler{…}


      public class DefaultOrderHandler : OrderHandler{…}


 


      public class OrderService


      {


            public void ReceiveOrder(Order order)


            {


                  // Do some logging or security or something valuable


                  OrderHandler handler = createHandlerChain();


                  handler.ProcessOrder(order);


            }


 


            // In real life you might pull the nodes in the Chain of Responsibility


            private OrderHandler createHandlerChain()


            {


                  OrderHandler topHandler = new LargeOrderHandler();


                  topHandler.AppendSibling(new EuropeanOrderHandler());


                  topHandler.AppendSibling(new LargeOrderHandler());


                  topHandler.AppendSibling(new MostFavoredCompanyHandler());


                  topHandler.AppendSibling(new DefaultOrderHandler());


 


 


                  return topHandler;


            }


      }


 


OrderService itself can be rapidly extended by creating new OrderHandler subclasses and popping them into the createHandlerChain() method.  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 to OrderService.  In a very complex system you might use some sort of Plugin pattern infrastructure to add OrderHandler’s through configuration or run time bootstrapping.  As a shameless plug, I did exactly this on a project that used StructureMap to configure a list of translation handlers.


 


From a testability standpoint the CoR pattern can be beneficial because it lets you unit test in smaller chunks.  I purposely left the CanHandle() method accessible as a public method.  When you test really complicated conditional processing logic you can make the unit testing easier by separately testing the decision to do an action from the action itself.  In concrete terms, when we test an OrderHandler class we can write separate, simpler unit tests for CanHandle() and handleRequest(). 


 


Subclasses of OrderHandler override the CanHandle() and handleRequest() abstract methods, but the general workflow is implemented in the abstract superclass.  That’s a textbook example of a Template pattern.  One thing to keep in mind is that patterns often occur together in the same class or cluster of classes.  Another more important thing to remember about design patterns is they’re just things that you do all the time in code, not some kind of new magic.


 


Alternative Implementation


 


I don’t have any kind of CompSci background in “pure” languages like LISP and C++, so linked lists seem weird to me.  I will usually put the possible handlers in an array.  The caller iterates over the array until it finds a handler that can handle the request and executes that handler.  It’s identical in effect, just different.  I think it makes the Plugin mechanics simpler, but that might be the tail wagging the dog.


 


Other Examples of Chain of Responsibility


 



  • Single sign on security solutions for web applications.  You might have a handler to check if the user is already authenticated, another handler to check for windows authentication, and a last handler to transfer the request to a logon page.

  • Last week I worked on a CoR implementation that analyzed exceptions coming back from a messaging component to diagnose the exception for production support.  Eventually this implementation might have handlers to resubmit the request or provide guidance for production support.  The list of handlers will have to be able to grow in the future.

  • The CoR pattern happens pretty frequently in conjunction with Composite structures

 


And How Not to Use Patterns


 


For about 18 months I was by far the youngest guy on a centralized architecture team (think of every bad thing you’ve ever thought or heard about a central architecture team and apply them here).  I took a perverse pleasure in correcting my peers whenever they misused a pattern name.  One day our most senior and highly paid architect was finally showing us his new world order for SOA utopia.  He kept mislabeling his proposed, elaborate architecture for creating all new web services as a “Chain of Responsibility” pattern and I kept telling him that he was wrong (He was really just using some EJB equivalent of chaining IHttpModule’s together in IIS for things like security and logging).  Don’t ever be the pedantic ass or the idiot spouting patterns who’s talking out of his ass.  Then again, it’s awfully fun to verbally abuse beard-stroking, non-coding architects.


 

About Jeremy Miller

Jeremy is the Chief Software Architect at Dovetail Software, the coolest ISV in Austin. Jeremy began his IT career writing "Shadow IT" applications to automate his engineering documentation, then wandered into software development because it looked like more fun. Jeremy is the author of the open source StructureMap tool for Dependency Injection with .Net, StoryTeller for supercharged acceptance testing in .Net, and one of the principal developers behind FubuMVC. Jeremy's thoughts on all things software can be found at The Shade Tree Developer at http://codebetter.com/jeremymiller.
This entry was posted in Design Patterns. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Zgsddzly

    I am sorry I still couldn’t understand. Seems so weird.

  • Eric Turnbow

    I like the example of use. From past projects, I see how I could have used a CoR to improve programming. Very easy to understand. Thanks!

  • Rajat

    Hi,
    Thanks for sharing this.Very well written.I just read a few books and couldnot get a grasp of this pattern.Now after reading this article, it did become clear to me.

  • http://nchain.sourceforge.net plpasta

    Hi. In case you would need generic, ready-to-use CoR implementation for .NET or Mono you can try this: http://nchain.sourceforge.net . I’ll appreciate any feedback :) Cheers, P.

  • Jiho Han

    First of all, I really enjoy your posts! Keep up the good work.

    I am a bit confused though regarding your last paragraph. Isn’t chaining multiple IHttpModules in fact an implementation of CoR pattern? Or am I missing something?

  • ashapochka

    Jeremy,

    With pleasure! I can send you the relevant sources by email if it’s ok with you. Just send me a message on ashapochka at gmail dot com and I will reply with the src for the CompositeMementoSource, Chains and the rest of it. I’d really enjoy having the functionality in the official StructureMap

    Andriy.

  • Jeremy D. Miller

    Andriy,

    Is there any chance you could send me something about what you did? That sounds like something interesting to get into the next version. I have some situations where that would be useful.

  • http://codebetter.com/blogs/ben.reichelt/ Ben Reichelt

    Michael, No I didnt finish reading before commenting, I had to go back :)

  • Michael

    Now, what I want to know, Ben, is whether or not you were able to finish reading the post before you responded ;)

  • http://codebetter.com/blogs/ben.reichelt/ Ben Reichelt

    Kevin Bacon, Animal House :)

  • ashapochka

    It may be interesting to note, I’ve recently reimplemented the Apache Commons chain library (its generic part) in C# and they have the chain’s XML configuration built on top of the other Apache Commons libraries, so it would have taken lots of time to reproduce it in C# and I decided to use your StructureMap as a configuration framework instead. I must say the two work together beautifully. Abstract Commands become PluginFamilies and their various implementations and chains become Plugins. The only problem has been your PluginFamilies configured in xml accept a single external memento source XOR embedded mementos and this was unfortunate since StructureMap.config quickly grew cluttered with all kinds of command and chain instance configurations.

    I seem to have solved the problem though. I implemented an additional class CompositeMementoSource that holds references to the child MementoSources and delegates to them containsKey and retrieveMemento calls on itself.
    So in MementoSourceMapper.ReadFromXml(…) I create an instance of CompositeMementoSource , add all found external XmlFile sources and the EmbeddedMememntoSource to it and then return it for PluginFamily.Source initialization. And that’s it. Now I can configure several external memento sources as well as embedded instances within one PluginFamily xml node in StructureMap.config.

    I thought it would be great to have this feature in the next StructureMap release.