Chain of Responsibility Pattern
Pros
- Multiple objects can handle a request without knowing which at runtime
Cons
- A performance impact from going through multiple objects for a request
- Can be difficult to debug
Example Explanation
LoanApprover - Has a member field containing the next link in a chain of responsibilities for fulfilling a request by the client
Manager - Concrete implementation of a LoanApprover. If an expense is too high for a manager to approve it uses if the next LoanApprover in the chain is capable of approving a loan

class Main {
public static void main(String[] args) {
LoanApprover man = new Manager();
LoanApprover dir = new Director();
LoanApprover vice = new VicePresident();
LoanApprover pres = new President();
man.setNextApprover(dir);
dir.setNextApprover(vice);
vice.setNextApprover(pres);
man.approveLoan( new Loan(3312));
man.approveLoan( new Loan(7500));
man.approveLoan( new Loan(21250));
man.approveLoan( new Loan(60000));
man.approveLoan( new Loan(250000));
}
}
abstract class LoanApprover {
protected LoanApprover nextApprover;
protected int approvalLimit;
private String rank;
public LoanApprover(String rank, int approvalLimit){
this.rank = rank;
this.approvalLimit = approvalLimit;
}
public void setNextApprover(LoanApprover nextApprover){
this.nextApprover = nextApprover;
}
public void approveLoan(Loan loan){
if (approvalLimit > loan.getAmount() ){
System.out.println(rank+" approves loan of "+loan.getAmount());
return;
}
nextApprover.approveLoan(loan);
}
}
class Manager extends LoanApprover{
public Manager(){
super("Manager", 5000);
}
}
class Director extends LoanApprover{
public Director(){
super("Director", 10000);
}
}
class VicePresident extends LoanApprover{
public VicePresident(){
super("Vice President", 25000);
}
}
class President extends LoanApprover{
public President(){
super("President", 100000);
}
@Override
public void approveLoan(Loan loan){
if(loan.getAmount() > approvalLimit){
System.out.println("Loan of "+loan.getAmount()+" denied by President");
return;
}
else{
super.approveLoan(loan);
}
}
}
class Loan{
private int amount;
public Loan(int amount){
this.amount = amount;
}
public int getAmount(){ return amount; }
}
Extra Resources