设计模式之责任链模式
什么是责任链模式(Chain of Responsibility)
生活中的责任链模式:击鼓传花,申请折扣,公司层结构
- 很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。
责任链模式涉及到的角色如下所示:
- 抽象处理者(Handler)角色:定义出一个处理请求的接口。如果需要,接口可以定义 出一个方法以设定和返回对下家的引用。这个角色通常由一个Java抽象类或者Java接口实现。
- 具体处理者(ConcreteHandler)角色:具体处理者接到请求后,可以选择将请求处理掉,或者将请求传给下家。由于具体处理者持有对下家的引用,因此,如果需要,具体处理者可以访问下家。
下面我们已Customer购买需要折扣为例简单介绍责任链模式:
/**
* 价格处理人,负责处理客户折扣申请
*/
public abstract class PriceHandler {
// 直接后继,用于传递申请
protected PriceHandler successor;
public void setSuccessor(PriceHandler successor) {
this.successor = successor;
}
// 折扣数量
public abstract void processDiscount(float number);
}
public class Sales extends PriceHandler {
// 销售可以批准5%以内的折扣
@Override
public void processDiscount(float number) {
if (number <= 0.05) {
System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), number);
} else {
successor.processDiscount(number);
}
}
}
public class Manger extends PriceHandler{
// 管理者可以批准20%以内的折扣
@Override
public void processDiscount(float number) {
if (number <= 0.2) {
System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), number);
} else {
successor.processDiscount(number);
}
}
}
/**
* CEO 可以配准小于50的折扣,大于50就拒绝申请
*/
@Override
public void processDiscount(float number) {
if(number<=0.5){
System.out.format("%s批准了折扣:%.2f%n", this.getClass().getName(), number);
}else{
System.out.format("%s拒绝了折扣:%.2f%n", this.getClass().getName(), number);
}
}
}
public class PriceHandlerFactory {
/**
* 创建PriceHandler的工厂方法
* @return
*/
public static PriceHandler creater() {
PriceHandler sales = new Sales();
PriceHandler manger = new Manger();
PriceHandler ceo = new CEO();
//设置后继
sales.setSuccessor(manger);
manger.setSuccessor(ceo);
//最后返回一个Handler去处理客户端的请求,此处返回一个销售者(责任链的第一个Handler).
return sales;
}
}
import java.util.Random;
//客户申请折扣
public class Customer {
private PriceHandler handler;
public void setHandler(PriceHandler handler) {
this.handler = handler;
}
public void requstnumber(float number) {
handler.processDiscount(number);
}
public static void main(String[] args) {
Customer customer = new Customer();
customer.setHandler(PriceHandlerFactory.creater());
//客户端并不知道链上的哪一个接受者会处理这个请求,从而实现了客户端和接受者之间的解耦
customer.requstnumber(new Random().nextFloat());
}
}
责任链模式的应用:
异常处理:我们的方法调用是一个栈,当我们栈顶的方法产生异常时,需要将异常抛出,这个异常将沿着异常链向下发展去寻找处理的块。此时被栈顶抛出的异常就是一个请求,我们调用一级方法就相当于一个Handler,这个Handler可以自己处理,也可以调用下一级处理。