责任链模式(Chain of Responsibility Pattern)
定义:
责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。
责任链模式是一种对象的行为模式。
在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。
这使得系统可以在不影响客户端的情况下动态地重新组织和分配责任。链有起始对象,有终止对象。
意图:避免请求发送者与接收者耦合在一起,让多个对象都有可能接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。
何时使用:在处理消息的时候以过滤很多道。
如何解决:拦截的类都实现统一接口。
应用实例:retrofit的拦截器。
使用场景: 1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。 2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。 3、可动态指定一组对象处理请求。
demo:模拟一个请假的流程,员工请假需要上级批准,对不同的请假天数,各个领导的权限不一样。
LeaveRequest.java
public class LeaveRequest {
private String name;
private int leaveDays;
private String reason;
public LeaveRequest(String name, int leaveDays, String reason) {
super();
this.name = name;
this.leaveDays = leaveDays;
this.reason = reason;
}
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 String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
}
创建抽象的记录器类。
public abstract class Leader {
String name;
Leader nextLeader; //责任链上的后继对象
public Leader(String name) {
super();
this.name = name;
}
// 设定责任链上的后继对象
public void setNextLeader(Leader nextLeader) {
this.nextLeader = nextLeader;
}
public abstract void handleRequest(LeaveRequest request);
}
创建扩展了该记录器类的实体类。
Director.java
public class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
int days = request.getLeaveDays(); //获取请假天数
String name = request.getName(); //获取请假人姓名
String reason = request.getReason(); // 获取请假理由
if(days <= 3) { //如果满足3天内的要求,主任直接审批
System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);
System.out.println("主任" + this.name + "审批通过");
} else {
System.out.println("请假天数过多,主任" + this.name + "没法处理");
if(this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理
this.nextLeader.handleRequest(request);
}
}
}
}
Manager.java
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
int days = request.getLeaveDays(); //获取请假天数
String name = request.getName(); //获取请假人姓名
String reason = request.getReason(); // 获取请假理由
if (days <= 10) { //如果满足10天内的要求,经理直接审批
System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);
System.out.println("经理" + this.name + "审批通过");
} else {
System.out.println("请假天数过多,经理" + this.name + "没法处理");
if (this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理
this.nextLeader.handleRequest(request);
}
}
}
}
GeneralManager.java
public class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
int days = request.getLeaveDays(); //获取请假天数
String name = request.getName(); //获取请假人姓名
String reason = request.getReason(); // 获取请假理由
if (days <= 30) { //如果满足30天内的要求,总经理直接审批
System.out.println("员工" + name + "请假" + days + "天,理由:" + reason);
System.out.println("总经理" + this.name + "审批通过");
} else {
System.out.println("请假天数过多,总经理" + this.name + "没法处理");
if (this.nextLeader != null) { //否则,如果链上存在下一个Leader,就让他处理
this.nextLeader.handleRequest(request);
} else {
System.out.println("请假不成功");
}
}
}
}
TestDemo.java
public static void main(String[] args) throws Exception {
Leader director = new Director("张三");
Leader manager = new Manager("李四");
Leader gManager = new GeneralManager("王五");
director.setNextLeader(manager);
manager.setNextLeader(gManager);
// 开始请假操作
LeaveRequest request = new LeaveRequest("倪升武", 15, "在家睡觉");
director.handleRequest(request);
}
运行结果
请假天数过多,主任张三没法处理
请假天数过多,经理李四没法处理
员工倪升武请假15天,理由:在家睡觉
总经理王五审批通过