介绍:
避免请求发送者和接受者耦合在一起,让多个对象都有可能接收请求将这些对象连接成一条链,并沿着这条链传递请求,直到有对象处理它为止.
主要角色:
抽象处理者(Handler)
抽象处理者定义了一个处理请求的接口,它一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求方法.因为每个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个自类型(抽象处理者类型)的对象,作为其对下家的引用
具体处理者(ConcreteHandler)
具体处理者是抽象处理者的子类,它可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理,否则将转发给后续者
客户类(Client)
用于向链中提出最初的请求,客户类只需要关心链的源头,而无需关心请求的处理环节以及请求的传递过程
结构图:
使用场景(适用环境):
- 有多个对象可以处理同一个请求,具体哪个对象处理改请求由运行时刻自动确定.客户端只需要将请求提交到链上,无需关心请求对象处理是谁以及它是如何处理的
- 在不明确接收者的情况下,向多个请求中的一个提交一个请求,请求的发送与请求的处理者解耦,请求将沿着连传递,寻求相应的处理者
- 可动态指定一组对象处理请求.客户端可以动态创建责任链来处理请求,还可以动态改变链中处理者之间的先后顺序
优点:
- 降低耦合度.一个对象无需指定其他哪个对象处理请求
- 简化对象相互连接.请求处理对象仅需维持一个指向其后续者的引用,而不需维持它对所有候选者处理引用
- 增强对象的指派职责的灵活性.给对象分配职责时,责任链可以给我们带来更多的灵活性
- 增加新的请求处理类很方便
缺点:
- 不能保证请求一定会被接收,既然一个请求没有明确的接收者,那么不能保证它一定会处理
- 对于比较长的责任链,请求的处理可能设计到多个处理对象,系统性能收到一定的影响
案例:
某oa系统需要提供一个请教条审批模块,如果员工请假天数小于3天,主任可以审批改请教条,如果该员工请假天数大于等于3天小于10天,经理可以审批,如果超大于10天小于30天总经理可以审批,如果超过30天,总经理也不能审批,并且提供相应的拒绝信息
结构图:
代码:
请求类:
public abstract class Leader {
protected String name;
protected Leader successor;
public Leader(String name) {
this.name = name;
}
public void setSuccessor(Leader successor) {
this.successor = successor;
}
public abstract void handleRequest(LeaveRequest request);
}
抽象处理者:
public class LeaveRequest {
private String leaveName;
private int leaveDays;
public LeaveRequest(String leaveName, int leaveDays) {
this.leaveName = leaveName;
this.leaveDays = leaveDays;
}
public String getLeaveName() {
return leaveName;
}
public void setLeaveName(String leaveName) {
this.leaveName = leaveName;
}
public int getLeaveDays() {
return leaveDays;
}
public void setLeaveDays(int leaveDays) {
this.leaveDays = leaveDays;
}
}
具体处理者:
public class Director extends Leader {
public Director(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 3) {
System.out.println("主任" + name + "审批了员工"
+ request.getLeaveName() + "请假条,请假天数为:"
+ request.getLeaveDays());
} else {
if (this.successor != null) {
this.successor.handleRequest(request);
}
}
}
}
public class Manager extends Leader {
public Manager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 10) {
System.out.println("经理" + name + "审批了员工"
+ request.getLeaveName() + "请假条,请假天数为:"
+ request.getLeaveDays());
} else {
if (this.successor != null) {
this.successor.handleRequest(request);
}
}
}
}
public class GeneralManager extends Leader {
public GeneralManager(String name) {
super(name);
}
@Override
public void handleRequest(LeaveRequest request) {
if (request.getLeaveDays() < 30) {
System.out.println("总经理" + name + "审批了员工"
+ request.getLeaveName() + "请假条,请假天数为:"
+ request.getLeaveDays());
} else {
System.out.println("请假天数太多,不予假期!");
}
}
}
测试:
public static void main(String[] args) {
//三个具体处理者
Leader leader1 = new Director("老王");
Leader leader2 = new Manager("老李");
Leader leader3 = new GeneralManager("老赵");
leader1.setSuccessor(leader2);
leader2.setSuccessor(leader3);
LeaveRequest request = new LeaveRequest("小王",2);
leader1.handleRequest(request);
LeaveRequest request2 = new LeaveRequest("小花",5);
leader1.handleRequest(request2);
LeaveRequest request3 = new LeaveRequest("小明",12);
leader1.handleRequest(request3);
LeaveRequest request4 = new LeaveRequest("小张",32);
leader1.handleRequest(request4);
}
结果: