1、理解责任链模式
在现实生活中,常常会出现这样的事例:一个请求有多个对象可以处理,但每个对象的处理条件或权限不同。
例如
- 公司员工请假,可批假的领导有部门负责人、副总经理、总经理等,但每个领导能批准的天数不同,员工必须根据自己要请假的天数去找不同的领导签名,也就是说员工必须记住每个领导的姓名、电话和地址等信息,这增加了难度。
- 找领导出差报销
- 生活中的“击鼓传花”游戏。
2、责任链模式的结构图
- 抽象处理者(Handler):定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
- 具体处理者(ConcreateHandlerA、ConcreateHandlerB):实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
-
客户类(Client):创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节和请求的传递过程。
image.png
3、责任链模式简单代码的具体实现
- 定义一个抽象处理类Handler
/**
* @author lichunlan
* @description 责任者模式的抽象处理类
* @since 2020-03-04
*/
public abstract class Handler {
/**
* 后继链接
*/
protected Handler successor;
public Handler getSuccessor() {
return successor;
}
public void setSuccessor(Handler successor) {
this.successor = successor;
}
/**
* 具体的抽象处理方法
*/
protected abstract void selfHandlerProcess();
/**
* 链头的具体处理者
*/
public void executed(){
selfHandlerProcess();
if(null != successor){
successor.executed();
}
}
}
- 具体处理者
注意我是把这几个类的定义放到public static void main(String[] args) {}同一个类中的
static class ConcreateHandlerA extends Handler{
@Override
protected void selfHandlerProcess() {
System.out.println("处理A");
}
}
static class ConcreateHandlerB extends Handler{
@Override
protected void selfHandlerProcess() {
System.out.println("处理B");
}
}
static class ConcreateHandlerC extends Handler{
@Override
protected void selfHandlerProcess() {
System.out.println("处理C");
}
}
- 客户类(Client)
public static void main(String[] args) {
Handler handlerA = new ConcreateHandlerA();
Handler handlerB = new ConcreateHandlerB();
Handler handlerC = new ConcreateHandlerC();
handlerA.setSuccessor(handlerB);
handlerB.setSuccessor(handlerC);
handlerA.executed();
}
-
运行的结果
image.png
4、责任链模式3中代码的优化
从图中可以看到,假设我们有20个具体处理者,那我们得重复写20遍这个代码,很明显需要优化
我们把所有的具体处理者放到一个List中,
image.png
- 抽象处理者
/**
* @author lichunlan
* @description 抽象处理者
* @since 2020-03-05
*/
public abstract class ChainHandler {
/**
* 具体的抽象处理方法
*/
protected abstract void selfHandlerProcess();
/**
* 链头的具体处理者
*/
public void executed(Chain chain){
selfHandlerProcess();
chain.progress();
}
}
- 链接类,把所有的具体处理者放到一个List中
/**
* @author lichunlan
* @description 把具体处理者封装成一个List
* @since 2020-03-05
*/
public class Chain {
List<ChainHandler> handlerList;
private int index = 0;
public Chain(List<ChainHandler> handlerList) {
this.handlerList = handlerList;
}
/**
* 把所有的具体处理者链接起来
*/
public void progress(){
if(index >= handlerList.size()){
return;
}
handlerList.get(index++).executed(this);
}
}
- 具体处理者
注意我是把这几个类的定义放到public static void main(String[] args) {}同一个类中的
static class ConcreateHandlerA extends ChainHandler {
@Override
protected void selfHandlerProcess() {
System.out.println("处理A");
}
}
static class ConcreateHandlerB extends ChainHandler{
@Override
protected void selfHandlerProcess() {
System.out.println("处理B");
}
}
static class ConcreateHandlerC extends ChainHandler{
@Override
protected void selfHandlerProcess() {
System.out.println("处理C");
}
}
- 客户类(Client)
public static void main(String[] args) {
List<ChainHandler> chainHandlerList = Arrays.asList(new ConcreateHandlerA(),new ConcreateHandlerB(),new ConcreateHandlerC());
Chain chain = new Chain(chainHandlerList);
chain.progress();
}
-
运行结果
image.png
5、责任链模式的使用场景
有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定。
可动态指定一组对象处理请求,或添加新的处理者。
在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。
总结:
对于设计模式来说,简单的demo应用,看懂了感觉也没多大实用性,因为自己还是不知道项目中具体该如何应用,所有我在看设计模式的时候,尽量去找哪些源码中用到了,然后实际再分析一下,自己画一个UML图,对于自己的理解和实际应用都有很大的提升。我看过一篇文章说OkHttp3、Netty NIO、Spring Aop都用到了责任链模式,于是接下来的另外一篇文章,从OKHttp源码中看责任链模式是关于如何从别人的源码精华中,真正看懂责任链模式。
网友评论