Chain of Responsibility pattern

Definition


Let more than one object handle a request without their knowing each other. Pass the request to chained objects until it has been handled.

Where to use & benefits

One request should be handled by more than one object.
Don't know which object should handle a request, probably more than one object will handle it automatically.
Reduce coupling.
Flexible in handling a request.

Related patterns include

Composite, which a chain of responsibility pattern is often applied in conjunction with.

Example


The Java Servlet filter framework is an example of chain of resposibility design. Note that the chain.doFilter() is the method that should be called to make the chain roll. If the subclass missed it, the whole chain would be stopped or blocked.

Java exception handling is another example of chain of responsibility design. When an error occurs, the exception call will look for a handling class. If there is no handler, the super Exception class will be called to throw the exception. Otherwise, the handler class will handle it.

Here comes a simple example, just to show how chain of responsibility works. Whenever you spend company's money, you need get approval from your boss, or your boss's boss. Let's say, the leadership chain is:
   Manager-->Director-->Vice President-->President

The following is a command line program to check who is responsible to approve your expenditure.
import java.io.*;
abstract class PurchasePower {

    protected final double base = 500;
    protected PurchasePower successor;

    public void setSuccessor(PurchasePower successor){
        this.successor = successor;
    }

    abstract public void processRequest(PurchaseRequest request);
}

class Manager extends PurchasePower {
    private final double ALLOWABLE = 10 * base;

    public void processRequest(PurchaseRequest request ) {
        if( request.getAmount() < ALLOWABLE )
            System.out.println("Manager will approve $"+ request.getAmount());
        else
           if( successor != null)
               successor.processRequest(request);
  }
}

class Director extends PurchasePower {
    private final double ALLOWABLE = 20 * base;

    public void processRequest(PurchaseRequest request ) {
        if( request.getAmount() < ALLOWABLE )
            System.out.println("Director will approve $"+ request.getAmount());
        else
           if( successor != null)
               successor.processRequest(request);
  }
}

class VicePresident extends PurchasePower {
    private final double ALLOWABLE = 40 * base;

    public void processRequest(PurchaseRequest request) {
        if( request.getAmount() < ALLOWABLE )
            System.out.println("Vice President will approve $" + request.getAmount());
        else
        if( successor != null )
            successor.processRequest(request);
  }
}

class President extends PurchasePower {
    private final double ALLOWABLE = 60 * base;
  
    public void processRequest(PurchaseRequest request){
        if( request.getAmount() < ALLOWABLE )
            System.out.println("President will approve $" + request.getAmount());
        else
            System.out.println( "Your request for $" + request.getAmount() + " needs a board meeting!");
    }
}

class PurchaseRequest {
 
    private int number;
    private double amount;
    private String purpose;

    public PurchaseRequest(int number, double amount, String purpose){
        this.number = number;
        this.amount = amount;
        this.purpose = purpose;
    }

    public double getAmount() {
        return amount;
    }
    public void setAmount(double amt){
        amount = amt;
    }
   
    public String getPurpose() {
        return purpose;
    }
    public void setPurpose(String reason) {
        purpose = reason;
    }

    public int getNumber(){
        return number;
    }
    public void setNumber(int num) {
        number = num;
     }  
}

class CheckAuthority {
    public static void main(String[] args) throws Exception{
        Manager manager = new Manager();
        Director director = new Director();
        VicePresident vp = new VicePresident();
        President president = new President();
        manager.setSuccessor(director);
        director.setSuccessor(vp);
        vp.setSuccessor(president);
       
        //enter ctrl+c to kill.
        while (true) {
            System.out.println("Enter the amount to check who should approve your expenditure.");
            System.out.print(">");
            double d = Double.parseDouble(new BufferedReader(new InputStreamReader(System.in)).readLine());
            manager.processRequest(new PurchaseRequest(0, d, "General"));
        }

  }
}

You may redo it using interface instead of abstract class.

The composite pattern is often used with chain of responsibility. That means a class may contain the related class that may handle the request.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值