JavaScript Design Patterns: Chain of Responsibility

We've made it to the final installment in the JavaScript Design Patterns series. That's right, after this you'll no longer have any clue what post will be coming out every Monday! Well today, we'll be talking about the Chain of Responsibility Pattern. This pattern decouples the sender and receiver of a request. This is done with a chain of objects, each of which can handle the request itself or pass it on to the next object. Confused? Read on.

The rest of the JavaScript Design Patterns series:

Chain of Responsibility Structure

There are three parts to the Chain of Responsibility pattern: sender, receiver, and request. The sender makes the request. 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.

A sender sends the request to the first receiver object in the chain. The sender only knows about this first object and nothing about the other receivers. The first receiver either handles the request and/or passes it on to the next one in the chain. Each receiver only knows about the next receiver in the line. The request will keep going down the line until the request was handled or there are no more receivers to pass it on to, at which point either nothing happens or an error is thrown, depending on how you want it to work.

Chains in the World Around Us

Event handling in the DOM uses one implementation of the Chain of Responsibility (amazing how many patterns are used together in the DOM, isn't it). Once an event is fired, it bubbles up the DOM hierarchy, calling every event handler it runs into until it either gets to the end of the chain or a handler tells it to stop propagating.

Chain of Responsibility Example

For our example today, we'll be creating an ATM. The Chain is going to consist of different sized bills. When you ask for some cash, the machine starts at the larger bills and pulls out as many as it needs, then moves on to the smaller bills. This example is very simple, which helps show the concept more clearly without diluting the code with implementations that are specific to the example.

Chain of Responsibility:ATM

We'll start by creating the receiver class: MoneyStacks. Normally this would just be an abstract class or interface that would be subclassed/implemented to create numerous 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, so we can just set that number via a parameter in the constructor.

var MoneyStack = function(billSize) {
    this.billSize = billSize;
    this.next = null;
}
MoneyStack.prototype = {
    withdraw: function(amount) {
        var numOfBills = Math.floor(amount / this.billSize);
        
        if (numOfBills > 0) {
            // Eject the bills
            this._ejectMoney(numOfBill);
            // Shrink the amount by how much money we ejected
            amount = amount - (this.billSize * numOfBills);
        }
        
        // If there is any money left to withdraw and if we have
        // another stack in the line, pass the request on
        amount > 0 && this.next && this.next.withdraw(amount);
    },
    // set the stack that comes next in the chain
    setNextStack: function(stack) {
        this.next = stack;
    },
    // private method that ejects the money
    _ejectMoney: function(numOfBills) {
        console.log(numOfBills + " $" + this.billSize 
            + " bill(s) has/have been spit out");
    }
}

It's all pretty simple math. withdraw is the function that uses the chaining ability by ejecting the required bills and passing the request on when appropriate.

Now, we'll build the ATM. Its constructor creates all of the money stacks and puts them into their hierarchical order. When someone calls its withdraw method, it just passes on the responsibility to the chain of money stacks.

var ATM = function() {
    // Create the stacks of money
    // We'll show you the implementation for this next
    var stack100 = new MoneyStack(100),
        stack50 = new MoneyStack(50),
        stack20 = new MoneyStack(20),
        stack10 = new MoneyStack(10),
        stack5 = new MoneyStack(5),
        stack1 = new MoneyStack(1);
    
    // Set the hierarchy for the stacks
    stack100.setNextStack(stack50);
    stack50.setNextStack(stack20);
    stack20.setNextStack(stack10);
    stack10.setNextStack(stack5);
    stack5.setNextStack(stack1);
    
    // Set the top stack as a property
    this.moneyStacks = stack100;
}

ATM.prototype.withdraw = function(amount) {
    this.moneyStacks.withdraw(amount);
}

// USAGE
var atm = new ATM();
atm.withdraw(186);
/* outputs:
    1 $100 bill(s) has/have been spit out
    1 $50 bill(s) has/have been spit out
    1 $20 bill(s) has/have been spit out
    1 $10 bill(s) has/have been spit out
    1 $5 bill(s) has/have been spit out
    1 $1 bill(s) has/have been spit out
*/
atm.withdraw(72);
/* outputs:
    1 $50 bill(s) has/have been spit out
    1 $20 bill(s) has/have been spit out
    2 $1 bill(s) has/have been spit out
*/

Ending My Responsibilities

That's all there is to this pattern. It's pretty simple. Like the Command and Observer patterns, its purpose is to decouple senders and receivers but for different reasons and with different trade-offs. Due to its hierarchy structure, it's also similar to the Composite pattern, and can also be injected within the Composite pattern to make some of the methods more efficient.

Well, it's been fun taking you through all of these JavaScript design patterns. I hope you've learned something along the way. If you haven't read through them all, I highly recommend that you do. The list is included below. Remember, though, that just because you know a pattern, doesn't mean it is required for the task at hand (you know the old "when all you have is a hammer, everything looks like a nail" saying).

I also ask that if you found any of these design pattern posts helpful that you go ahead and let me know through a comment or spread the post around the internet to help others like us grow in JavaScript wisdom. You can do that using the links below, if you wish. As always, Happy Coding!

JavaScript Design Patterns series:

About the Author

Author: Joe Zim

Joe Zim

Joe Zimmerman has been doing web development ever since he found an HTML book on his dad's shelf when he was 12. Since then, JavaScript has grown in popularity and he has become passionate about it. He also loves to teach others though his blog and other popular blogs. When he's not writing code, he's spending time with his wife and children and leading them in God's Word.


  • 尤川豪

    I like this ATM example. It’s clean and clever
    Thank you very much :)