什么是责任链设计模式?
-
客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁是具体的处理对象。这样就实现了请求者和接受者之间的解耦,并且在客户端可以实现动态的组合职责链,使编程更有灵活性。
-
定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。其过程实际上是一个递归调用
要点主要是:
-
有多个对象共同对一个任务进行处理。
-
这些对象使用链式存储结构,形成一个链,每个对象知道自己的下一个对象。
-
一个对象对任务进行处理,可以添加一些操作后将对象传递个下一个任务。也可以在此对象,上结束任务的处理,并结束任务。
-
客户端负责组装链式结构,但是客户端不需要关心最终是谁来处理了任务。
责任链模式应用场景
-
多条件流程判断,权限控制。
-
ERP系统、流程审批
-
Java 过滤器底层实现 Filter
责任链设计模式如何保证顺序问题?
- 获取到责任链第一个,在第一个执行完成之后,在调用第二个进行执行,以此类推。
应用案例
- 小明因家里有事,需要请一个月的假,但他总不能直接就跑了吧,要是旷工一个月那他就彻底放假了,所以需要走公司流程跟领导请假,于是他就跟组长说,组长一看是一个月的假,他批不了,只能去找经理,而经理也没有这个权限,只能上报到董事长,由董事长亲自签字,最后这张请假条才能生效
实现案例
- 定义审批者抽象行为
/**
* 抽象类(定义共同行为)
*
* @author ext.liuyan10
* @date 2021/2/7 9:48
*/
public abstract class Handler {
/**
* 下一个责任链对象
*/
protected Handler next;
/**
* 处理事件
*/
public abstract void handleEvent();
}
- 组长审批
/**
* 责任链处理者(组长)
*
* @author ext.liuyan10
* @date 2021/2/7 9:52
*/
public class GroupLeaderHandler extends Handler {
public GroupLeaderHandler() {
ManagerHandler managerHandler = new ManagerHandler();
this.next = managerHandler;
}
@Override
public void handleEvent() {
System.out.println("组长:一个月的假我批不了,我给你找经理去");
this.next.handleEvent();
}
}
- 经理审批
/**
* 责任链处理者(经理)
*
* @author ext.liuyan10
* @date 2021/2/7 10:11
*/
public class ManagerHandler extends Handler {
public ManagerHandler() {
ChairmanHandler chairmanHandler = new ChairmanHandler();
this.next = chairmanHandler;
}
@Override
public void handleEvent() {
System.out.println("经理:这么长的假我也没权限审批,帮你交到董事长那,得他同意才行");
this.next.handleEvent();
}
}
- 董事长审批
/**
* 责任链处理者(董事长)
*
* @author ext.liuyan10
* @date 2021/2/7 10:13
*/
public class ChairmanHandler extends Handler {
public ChairmanHandler() {
}
@Override
public void handleEvent() {
System.out.println("董事长审批完成");
}
}
- 调用责任链
/**
* @author ext.liuyan10
* @date 2021/2/7 9:47
*/
public class ResponsilbillityApp {
public static void main(String[] args) {
GroupLeaderHandler groupLeaderHandler = new GroupLeaderHandler();
groupLeaderHandler.handleEvent();
}
}
- 执行结果
Connected to the target VM, address: '127.0.0.1:56500', transport: 'socket'
组长:一个月的假我批不了,我给你找经理去
经理:这么长的假我也没权限审批,帮你交到董事长那,得他同意才行
董事长审批完成
Disconnected from the target VM, address: '127.0.0.1:56500', transport: 'socket'
Process finished with exit code 0
网友评论