定义
责任链模式(Chain Of Responisibility):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
这种处理方式想斗罗大陆的主角遇见的事:泰隆想怼唐三,结果打不过。然后他的老子泰诺,出来找唐三,又被唐三击败后。再然后,泰诺的老子泰坦,又出来要解决唐三。。。。
责任链,就是,请求解决不了,向上传递,直到解决。
UML类图
角色及职能
- Handler:抽象的处理者,定义了一个处理请求的接口,同时含义另外Handler
- ConcreteHandler1,2是具体的处理者,处理它自己负责的请求,可以访问它的后继者(即下一个处理者),如果可以处理当前请求,则处理,否则就将该请求交个后继者去处理,从而形成一个职责链
案例
需求
学校的学习小组关于请假
规定:
- 一个小时以内,给自己请假
- 超过一个小鼠,四个小时以内,找自己小组长请假
- 超过四个小时,找老师请假
代码
Leader
public abstract class Leader {
private Leader next;
public Leader getNext() {
return next;
}
public void setNext(Leader next) {
this.next = next;
}
// 处理请求方法
public abstract void handleRequest(int LeaveDays);
}
YouSelf
public class YouSelf extends Leader{
@Override
public void handleRequest(int LeaveDays) {
if (LeaveDays<=1) {
System.out.println("请假成功,你自己批的假");
} else {
getNext().handleRequest(LeaveDays);
}
}
}
GroupLeader
public class GroupLeader extends Leader{
@Override
public void handleRequest(int LeaveDays) {
if (LeaveDays<=4) {
System.out.println("请假成功,组长批的假");
} else {
getNext().handleRequest(LeaveDays);
}
}
}
Teacher
public class Teacher extends Leader{
@Override
public void handleRequest(int LeaveDays) {
if (LeaveDays>4) {
System.out.println("请假成功,老师批的假");
} else {
getNext().handleRequest(LeaveDays);
}
}
}
Client
public class Client {
public static void main(String[] args) {
// 组装责任链
Leader youSelf = new YouSelf();
Leader groupLeader = new GroupLeader();
Leader teacher = new Teacher();
youSelf.setNext(groupLeader);
groupLeader.setNext(teacher);
// 提交请求
// 第一次请假
youSelf.handleRequest(1);
// 第二次请假
youSelf.handleRequest(3);
// 第三次请假
youSelf.handleRequest(6);
}
}
运行结果
请假成功,你自己批的假
请假成功,组长批的假
请假成功,老师批的假
优缺点
优点
- 降低耦合度。它将请求的发送者和接收者解耦。
- 简化了对象。使得对象不需要知道链的结构。
- 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
- 增加新的请求处理类很方便。
缺点
- 不能保证请求一定被接收。
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
- 可能不容易观察运行时的特征,有碍于除错。
使用场景
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可动态指定一组对象处理请求。