责任链模式
定义:为了避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止,这就是责任链模式。
举个栗子咯,当周杰伦要在你的城市开演唱会时,而你恰好有课,这时候咋办呢?总不能不去吧,所以只有向老师请假咯。而请假的话,是有个流程滴,当你提交申请表给辅导员时,如果天数在两天以内的话,辅导员直接给你批准啦,你就可以开溜啦;但是当你请假天数在两天以上,四天以内的时候,辅导员就没那个权力批准啦,它就只能把你的申请表交给学院院长,让院长批准啦;如果天数在四天到七天的话,院长也没法子处理啦,他只有把你的请假申请表交给校长啦;如果请假天数大于七天...抱歉,请假七天那还读个毛的书,一律否决,再附送个叫家长来校大礼包....
用编程语言来实现的话,估计很多人第一想到的就是写一大串if else 语句啦,但在之前讨论策略模式的时候,我们就以及说过了这样的弊端啦,所以我们就要用到我们的责任链模式啦
主要角色
Handler: 抽象处理者。定义了一个处理请求的方法。所有的处理者都必须实现该抽象类。
ConcreteHandler: 具体处理者。处理它所负责的请求,同时也可以访问它的后继者。如果它能够处理该请求则处理,否则将请求传递到它的后继者。
Client: 事件的发起者
实例
首先定义一个假条类
public class LeaveRequest {
private String name;
private int leaveDays;
public LeaveRequest(String name, int leaveDays) {
super();
this.name = name;
this.leaveDays = leaveDays;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLeaveDays() {
return leaveDays;
}
public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
}
定义抽象处理者
public abstract class Leader {
protected String name;
protected Leader nextLeader; //责任链上的后继对象
public Leader(String name) {
super();
this.name = name;
}
//设定责任链上的后继对象
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
/**
* 处理请求的核心的业务方法
* @param request
*/
public abstract void handleRequest(LeaveRequest request);
}
三个具体的处理者
辅导员
public class Instructor extends Leader{
public Instructor(String name) {
super(name);
}
public void handleRequest(LeaveRequest LeaveRequest) {
if(LeaveRequest.getLeaveDays() <= 2){ //小于2天辅导员审批
System.out.println("辅导员" + name + "审批" +LeaveRequest.getName() + "同学的请假条,请假天数为" + LeaveRequest.getLeaveDays()+ "天。");
}
else{ //否则传递给院长
if(this.nextLeader != null){
this.nextLeader.handleRequest(LeaveRequest);
}
}
}
}
院长
public class Dean extends Leader{
public Dean(String name) {
super(name);
}
public void handleRequest(LeaveRequest LeaveRequest) {
if(LeaveRequest.getLeaveDays() <= 4){ //小于4天院长审批
System.out.println("院长" + name + "审批" +LeaveRequest.getName() + "同学的请假条,请假天数为" + LeaveRequest.getLeaveDays()+ "天。");
}
else{ //否则传递给校长
if(this.nextLeader != null){
this.nextLeader.handleRequest(LeaveRequest);
}
}
}
}
校长
public class President extends Leader{
public President(String name) {
super(name);
}
public void handleRequest(LeaveRequest LeaveRequest) {
if(LeaveRequest.getLeaveDays() <= 7){ //小于7天校长审批
System.out.println("校长" + name + "审批" +LeaveRequest.getName() + "同学的请假条,请假天数为" + LeaveRequest.getLeaveDays()+ "天。");
}
else{
System.out.println("叫家长来");
}
}
}
客户端测试
public class Client {
public static void main(String[] args) {
Leader instructor = new Instructor("老王"); //辅导员
Leader dean = new Dean("老李"); //院长
Leader president = new President("老谢"); //校长
instructor.setNextLeader(dean); //辅导员的后续者是院长
dean.setNextLeader(president); //院长的后继者是校长
LeaveRequest le = new LeaveRequest("我", 1);
instructor.handleRequest(le);
le = new LeaveRequest("哥", 3);
instructor.handleRequest(le);
le = new LeaveRequest("qiu", 5);
instructor.handleRequest(le);
le = new LeaveRequest("ll", 11);
instructor.handleRequest(le);
}
}
适用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可动态指定一组对象处理请求。
实际开发中的应用
- Java中,异常机制就是一种责任链模式。一个try可以对应多个catch,当第一个catch不匹配类型,则自动跳到第二个catch.
- Javascript语言中,事件的冒泡和捕获机制。Java语言中,事件的处理采用观察者模式。
- Servlet开发中,过滤器的链式处理