Today, we’ll be talking about the Chain of Responsibility Pattern. This pattern decouples the sender and receiver of requests. This is done with a chain of objects that can each handle the request itself or pass it on to the next object. Confused? Read on.
Chain of Responsibility Structure
3 parts make up the Chain of Responsibility pattern: sender, receiver, and request. The sender makes requests. The receiver is a chain of 1 or more objects that choose whether to handle the request or pass it on. The request itself can be an object that encapsulates all the appropriate data, or it could just be a normal function call on the receiver with no arguments.
Senders send the request to the first receiver object in the chain. The sender only knows about this first part of the chain and nothing about the other receivers. The first receiver either handles the request or passes it on to the next receiver in the chain. Each receiver only knows about the next receiver in the line. The request will continue down the line until the request was handled or there are no more receivers to pass it on to, at which point either an error is thrown or nothing happens, depending on how you design your chain.
Chain of Responsibility Example
For our example, we’ll be creating an ATM. The chain is going to consist of different sized dollar bills. When you ask for some cash, the machine starts at the larger bills and pulls out as many of those that it needs, then moves on to the next smaller bill and so on until we’ve got all of the money or we run out of bills. This example is purposefully simple, because that helps to show the concept more clearly without diluting the code with too many example-specific implementations.
We’ll start by creating the receiver ‘class’: MoneyStacks. Normally this would just be an interface that would be implemented by different receivers, but this example is simple enough that the only variance between each of the receivers will be the size of the bills in the stack. We’ll just set that number via a parameter in the constructor.