Chain of Responsibility
linkChain of Responsibility


Chain of Responsibility is a behavioral design pattern that allows a request to be passed along a chain of commands without having to associate the class sending the request with the class receiving it.

Real World Example

The description of this pattern is a bit complicated, so let’s imagine that we are in a store, we have just done shopping and approach the cash register. The cashier has already checked our purchases and is waiting for payment. We have several types of payment to choose from:
  • voucher-up to $20
  • credit card-up to $200
  • cash-up to $100

Code Example

Let’s create the first class that will be responsible for handling payments. To create it, we will have to provide some type of payment: card, cash or voucher. Additionaly the class implements two extra methods:
  • success-if the transaction is successful, it returns a message depending on what we paid with
  • error-shows information that the transaction failed
class PaymentHandler
  attr_accessor :successor

  def initialize(successor = nil)
    @successor = successor

  def call(price)
    successor ? : error


  def success(message)

  def error
    "You are poor and have nothing to pay!"
The first way we will try to pay will be a Voucher. So let’s implement a class that will handle this payment. The voucher can be used to pay for purchases up to $20.
class VoucherPaymentHandler < PaymentHandler
  def call(price)
    price < 20 ? success('You paid by Voucher!') : super(price)
The next step will be to implement cash handler.
class CashPaymentHandler < PaymentHandler
  def call(price)
    price < 100 ? success('You paid by Cash!') : super(price)
And card handler.
class CardPaymentHandler < PaymentHandler
  def call(price)
    price < 200 ? success('You paid by Card!') : super(price)
At this point, we are able to implement our chain.

payment =
) => "You paid by Voucher!" => "You paid by Cash!" => "You paid by Card!" => "You are poor and have nothing to pay!"
Depending on what we pay with, the methods return success or if they are unable to handle the payment, they pass it on until the last link in the chain, which returns an error in case of failure.
A well-prepared chain allows you to handle an endless number of implementations and allows you to place specific handler anywhere in the chain.