How could I explain the Chain of Responsibility pattern to myself?
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.
- 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.
- 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.
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.
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.