Chain of Responsibility JavaScript Design Pattern

Category: Programming Tags: ,
March 29, 2012
code

By Joe J Zim

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.

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(numOfBills) {
  console.log(numOfBills + " $" + this.billSize
  + " bill(s) has/have been spit out");
  }
}

The math behind it is pretty simple. The withdraw function is what uses the chaining ability by ejecting the required bills and then passing the request on to the next in the chain when appropriate.

Now, we’ll build the ATM. Its constructor instantiates all of the money stacks and puts them into their hierarchical order. When someone calls the withdraw method on it, it the responsibility of withdrawing gets passed on 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 the sender from the receivers but for different reasons and with different trade-offs. Due to its hierarchical structure, it’s also similar to the Composite pattern, and can even be injected within the Composite pattern for some real fun.

Joe Zim
I’ve been programming with HTML, CSS, and JavaScript since I was 12 years old and I think JavaScript has won out against the other two to become my favorite language. I now maintain a JavaScript blog at http://www.joezimjs.com that I update twice a week while I work from home for an internet marketing company.

Article Source: http://EzineArticles.com/?expert=Joe_J_Zim
http://EzineArticles.com/?Chain-of-Responsibility-JavaScript-Design-Pattern&id=6896504

2 thoughts on “Chain of Responsibility JavaScript Design Pattern

  1. Pingback: URL

Comments are closed.