DEV Community

Klee Thomas
Klee Thomas

Posted on • Originally published at blog.kleeut.com

Chain of responsibility

How could I explain the Chain of Responsibility pattern to myself?

What is the Chain of Responsibility?

A series of classes or functions that are capable of handing certain requests.These handlers are connected in a linked list where each handler is aware of the next handler in the list, or chain. If a handler is not capable of handling the request then it calls the next providing the request.
The chain may be implemented such that multiple handlers can contribute to the completion of a single request. In this the request will need to be updated before being passed to the next handler.

Why is that a good idea?

  • It allows handers to be added or removed with minimal change to existing code.
  • It allows handlers to be re-ordered without editing the handlers or making large code changes.
  • Allows handling logic to be decoupled from other handling logic and tested independently.

Where would you use it?

  • At times where the execution order is likely to be changed often or dynamically.
  • At times when methods of processing a request need to be added or removed with minimal code changes or dynamically
  • To simplify complex if, else logic chains and decouple them into testable components.

ATM example.

The canonical example for explaining how the Chain of Responsibility works is using an ATM. Each denomination of money is provided as a handler. Ordered from largest to smallest.

To return $125
The $50 note handler run first scheduling 2 $50 notes to be given to the user and passes the request to the next handler.
The $20 note handler runs second scheduling 1 $20 note to be given to the user and passes the request on again.
The $10 note handler is not able to process the request and passes the request on.
The $5 note handler schedules 1 $5 note.
With nothing left to return the recursion completes and the scheduled money is given to the user.

What could go wrong?

  • No fall back handler.
    If no handler is specified to handle a command that is is unknown or not capable of being processed then there is a chance that the system will throw a null reference exception or complete without having finished processing the request.

  • Can be implemented in a way that tightly couples the order of the strategies
    Each handler should not be hard coded to know what is next in the chain. This creates unnecessary and undesirable coupling between the handlers. The next handler in the chain should be passed in as part of the constructor or be set by a higher order class.

    In the above example if the machine is out of $20 notes it should be able to dynamically remove the $20 handler without having to be re-coded.

Top comments (0)