1. 责任链模式:
定义:使多个对象都能处理请求,从而避免了请求的发送者和接受者之间的耦合关系,将这些对象连成一个链,并沿着这条链传递该请求,直到有对象能处理它为止。
2. 责任链模式的角色介绍:
a. 抽象处理者:抽象的处理者实现三个职责:一是定义一个请求的处理方法,唯一对外开放的方法;二是定义一个链的编排方法,设置下一个处理者;三是定义了具体的请求者必须实现的方法(子类可以通过实现这个方法来实现自己的业务逻辑)。一般为一个抽象类,使用模板方法模式
b. 具体的处理者:继承抽象处理者,实现各自处理请求的业务逻辑方法
3. 简单示例代码:
Request类 可以封装请求数据到此对象
/** * 请求信息类 * @author zqkj001 * */ public class Request { //请求等级 private int requestLevel; public int getRequestLevel() { return requestLevel; } public void setRequestLevel(int requestLevel) { this.requestLevel = requestLevel; } }Response类 接收处理结果信息
/** * 处理结果信息类 * @author zqkj001 * */ public class Response { private String result; public Response(String re) { this.result=re; } public String getResult() { return result; } }Handler类 抽象处理者类
public abstract class Handler { //定义下一级处理器,若自己不能处理则转给下一级 private Handler nextHandler; //每一个handler都要对请求做处理(模板方法模式的模板方法) public final Response handRequest(Request request){ Response response=null; //判断是否属于自己的处理级别,如果不是则转给下一级 if(this.getHandlerLevel()==request.getRequestLevel()){ response=this.doRequest(request); }else{ if (this.nextHandler!=null) { response=this.nextHandler.handRequest(request); }else{ response=new Response("无合适的处理者,退出"); } } return response; } //设置下一级处理器 public void setNextHandler(Handler handler){ this.nextHandler=handler; } //每一个处理器都有一个处理级别(模板方法的基本方法) protected abstract int getHandlerLevel(); //每一个处理器自己的请求处理逻辑(模板方法的基本方法) protected abstract Response doRequest(Request request); }Handler1、Handler2、Handler3 具体处理者类
public class MyHandler1 extends Handler { private final int level1=1; @Override protected int getHandlerLevel() { return this.level1; } @Override protected Response doRequest(Request request) { return new Response("handler1 execute success"); } }
public class MyHandler2 extends Handler { private final int level2=2; @Override protected int getHandlerLevel() { return this.level2; } @Override protected Response doRequest(Request request) { return new Response("handler2 execute success"); } }
public class MyHandler3 extends Handler { private final int level3=3; @Override protected int getHandlerLevel() { return this.level3; } @Override protected Response doRequest(Request request) { return new Response("handler3 execute success"); } }测试类:
public class Test { public static void main(String[] args) { //声明所有的处理节点 Handler handler1=new MyHandler1(); Handler handler2=new MyHandler2(); Handler handler3=new MyHandler3(); //设置链中的责任顺序 1-2-3 handler1.setNextHandler(handler2); handler2.setNextHandler(handler3); //构造请求信息 Request request=new Request(); request.setRequestLevel(3); //提交请求,返回结果 Response response=handler1.handRequest(request); System.out.println(response.getResult()); } }4. 示例代码对应的类图
5. 责任链模式的优点
责任链模式非常显著的优点是将请求和处理分开。请求者可以不用知道是谁处理的,处理者可以不用知道请求的全貌(例如在J2EE项目开发中,可以剥离出无状态Bean由责任链处理),两者解耦,提高系统的灵活性。
6. 责任链模式的缺点
责任链有两个非常显著的缺点:一是性能问题,每个请求都是从链头遍历到链尾,特别是在链比较长的时候,性能是一个非常大的问题。二是调试不很方便,特别是链条比较长,环节比较多的时候,由于采用了类似递归的方式,调试的时候逻辑可能比较复杂。
7. 责任链模式的注意事项
链中节点数量需要控制,避免出现超长链的情况,一般的做法是在Handler中设置一个最大节点数量,在setNext方法中判断是否已经是超过其阈值,超过则不允许该链建立,避免无意识地破坏系统性能。
8. 使用场景:
责任链模式屏蔽了请求的处理过程,你发起一个请求到底是谁处理的,这个你不用关心,只要你把请求抛给责任链的第一个处理者,最终会返回一个处理结果(当然也可以不做任何处理),作为请求者可以不用知道到底是需要谁来处理的,这是责任链模式的核心,同时责任链模式也可以作为一种补救模式来使用。举个简单例子,如项目开发的时候,需求确认是这样的:一个请求(如银行客户存款的币种),一个处理者(只处理人民币),但是随着业务的发展(改革开放了嘛,还要处理美元、日元等),处理者的数量和类型都有所增加,那这时候就可以在第一个处理者后面建立一个链,也就是责任链来处理请求,如果是人民币,好,还是第一个业务逻辑来处理;如果是美元,好,传递到第二个业务逻辑来处理;日元、欧元……这些都不用在对原有的业务逻辑产生很大改变,通过扩展实现类就可以很好地解决这些需求变更的问题。