小白设计模式:责任链模式
定义
将多个接收对象(处理者)组成链式结构,按序对输入的信号事件进行处理直到事件被处理。
主要组成
抽象处理者(Handler) : 责任链上每一环的处理对象,抽象处理接口。
具体处理者(concrete Handler) : 实现Handler相关接口,并持有责任链上下一个处理者的引用。对输入的事件进行判断,符合条件则截断事件传递并进行处理,否则将事件接着往下传递。
输入事件(request) : 输入到责任链请求被处理的事件信号
UML类图
image框架代码:
抽象处理者
public abstract class Handler {
//下一个处理者引用,末尾位置没有则为null
Handler nextHandler;
public Handler(Handler nextHandler) {
this.nextHandler = nextHandler;
}
public abstract void handRequest(Request request);
}
具体处理者
//具体处理者1
public class JsonHandler extends Handler{
public JsonHandler(Handler nextHandler) {
super(nextHandler);
}
@Override
public void handRequest(Request request) {
if (request.isJson()) {
//添加事件处理代码
System.out.println( "JsonHandler");
} else if (nextHandler != null) {
//调用下一个处理者处理事件
nextHandler.handRequest(request);
}
}
}
//具体处理者2
public class XmlHandler extends Handler{
public XmlHandler(Handler nextHandler) {
super(nextHandler);
}
@Override
public void handRequest(Request request) {
if (request.isXml()) {
//添加事件处理代码
System.out.println( "XmlHandler");
} else if (nextHandler != null) {
//调用下一个处理者处理事件
nextHandler.handRequest(request);
}
}
}
//具体处理者3
public class StringHandler extends Handler{
public StringHandler(Handler nextHandler) {
super(nextHandler);
}
@Override
public void handRequest(Request request) {
if (request.isString()) {
//添加事件处理代码
System.out.println( "StringHandler");
} else if (nextHandler != null) {
//调用下一个处理者处理事件
nextHandler.handRequest(request);
}
}
}
模拟事件对象
public class Request {
boolean isJson = false;
boolean isXml = false;
boolean isString = false;
public Request(boolean isJson, boolean isXml, boolean isString) {
this.isJson = isJson;
this.isXml = isXml;
this.isString = isString;
}
public boolean isJson() {
return isJson;
}
public boolean isXml() {
return isXml;
}
public boolean isString() {
return isString;
}
}
简单测试代码:
public class Main {
public static void main(String[] args){
Handler handler = new JsonHandler(new XmlHandler(new StringHandler(null)));
handler.handRequest(new Request(false, false, true));
}
}
打印:
StringHandler
该简单测试用例的链条组成顺序为:
JsonHandler --> XmlHandler --> StringHandler
则事件的传递与处理方向同样安装该顺序来:
JsonHandler.handRequest --> XmlHandler.handRequest --> StringHandler.handRequest
总结
优点
将事件的发送者与接受处理者解耦。(这边可以这么理解,假设不使用责任链,如果有5种事件对应可以处理的5个处理者,则调用方需要创建这5个处理者,并且一一调用各自的处理事件的方法。但是如果使用责任链,调用者不用关心有多少个处理者,因为提供给调用者的就只是责任链上的第一个元素,提供的是接口,相当于将整个责任链看做一个对象以接口的形式传递给调用者,调用者只需要调用这个对象的处理接口即可。)
简化了单个处理者处理逻辑,不需要判断并处理各种事件类型。处理者处不需要知道链的整体结构(但需要知道下一个处理者),只需要判断处理传递给自己的事件,如果无法处理则传递给下一个处理者。
可以动态的改变、调整责任链的成员组成,达到增加/删除或改变处理者的处理顺序。
缺点
可能存在事件传递到最后都没有被处理的情况(既是优点也是缺点)
效率上的影响,毕竟比所有处理都写在一起相比多了创建各个对象的消耗等
不容易观察运行时特征,排查问题相对麻烦
使用场景
多个对象都需要判断处理同一种事件类型时,例如android系统中事件分发等,这种链条式处理消息的场景。