1. 定义
- 官方定义:使多个对象都有机会处理请求,从而避免了请求的发送者和接受者的耦合关系。
将这些请求连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。
- .翻译:
为了避免请求发送者与多个处理者耦合在一起, 将所有请求的处理者通过前一个对象记住其后一个对象的引用而连成一个链;当请求发生时 将沿着这条链传递,直到处理结束。
2. 类图
3. 适用场景
一个请求的处理需要多个对象中的一个或多个协作处理
4. 优点
- 将请求者与处理者进行了解耦
发出请求的人只需要向第一个具体的处理者发送请求,然后就可以不用管了,处理者会在责任链上自己寻找处理的方法。 - 增强了系统的可扩展性。
可以根据需要增加新的请求处理类,满足开闭原则,即可以动态的改变责任,删除或者添加或者改变顺序,当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任 - 让各个处理者专注于实现自己的职责
每个处理者只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。 - 简化了对象之间的连接
每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。
3. 缺点
- 性能问题
每个请求都是从链头遍历到链尾,在链过长的情况下会出现很大的性能问题
解决方法:在Handler汇总设置一个最大节点数,在setNext方法中判断是否超过阈值,超过则不允许该链建 - 不能保证每个请求一定被处理
由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。
5. 代码模板(结合模板模式)
- 抽象处理类
public abstract class Handler {
private Handler nextHandler;
/**
* 设置下一个处理者 即链的编排方法
*/
public void setNextHandler(Handler handler) {
this.nextHandler = handler;
}
/**
* 处理级别
*/
protected abstract Level getHandlerLevel();
/**
* 具体的处理任务 自己本身的职责
*/
protected abstract Response echo(Request request);
/**
* 请求处理
*/
public final Response handleMessage(Request request) {
Response response = null;
//判断是否是自己的处理级别
if (this.getHandlerLevel().equals(request.getRequestLevel())) {
response = this.echo(request);
} else {
// 传递给下一个处理者
if (this.nextHandler != null) {
response = this.nextHandler.handleMessage(request);
} else {
System.out.println("流程结束");
}
}
return response;
}
}
- 具体处理类 ConcreteHandler
public class ConcreteHandler1 extends Handler{
@Override
protected Level getHandlerLevel() {
return null;
}
@Override
protected Response echo(Request request) {
return null;
}
}
- 请求客户端
public class Client {
public static void main(String[] args) {
Handler handler1 = new ConcreteHandler1();
Handler handler2 = new ConcreteHandler2();
Handler handler3 = new ConcreteHandler3();
//链顺序
handler1.setNextHandler(handler2);
handler2.setNextHandler(handler3);
Response response = handler1.handleMessage(new Request());
}
}