责任链模式
责任链模式是将多个请求处理者连接起来,形成链状,不同的处理者对请求有不同的处理能力。当请求发送后,请求将沿着链状的处理者传递,直到被某个处理者处理。责任链模式避免了请求发送者与处理者的耦合关系,发送者不需要知道谁来处理请求,并且让所有的处理者都有机会处理请求。
Java中我们经常使用的用于捕获异常信息的try catch就是责任链模式的体现:
try { //需要捕获异常的代码 } catch (Exception1 e1) { //处理第一种异常 } catch (Exception2 e2) { //处理第二种异常 } catch (Exception3 e3) { //处理第三种异常 }//...
try块中的代码作为请求发送者,产生的异常信息就是请求,而每个catch块都可以看作是接收一个特殊类型参数的方法,即请求处理者。当异常被抛出时,异常处理机制将寻找与异常类型相匹配的第一个处理程序,然后执行catch中的代码,即请求被该处理者处理了。
Android中事件分发机制也是责任链模式的应用。手指触摸屏幕时,系统将对应的事件包装成一个事件对象,事件将自顶向下按照Activity->Window->顶级ViewGroup->子View的顺序传递。一旦某个View的dispatchTouchEvent方法返回true,就表示这个处理者拦截了这个事件,接着这个事件将会被这个处理者处理,它的onTouchEvent方法将会被调用。
同样Android中的广播也可以按照责任链模式来使用,BroadcastReceiver就是处理者。我们知道,广播分为普通广播和有序广播,普通广播发送后,所有注册了该广播的接收器都将收到消息。而有序广播是按照优先级来传播的,优先级高的广播接收器将先收到消息,然后可以决定是否将广播继续传递出去。通过对注册同一个有序广播的多个广播接收器设置不同的优先级,即可实现责任链模式处理广播事件。
责任链模式实现:简单的责任链模式
举例,我们在公司请假时,大公司一般都有完整的流程,根据不同的请假时间,审批人也有所不同。比如,临时请假一会儿出去一趟,直接跟组长请假就好了。请假1-3天,需要部门主管审批。3-10天以上则需要部长审批。这里的组长、主管、部长都是请求处理者,于是创建抽象处理者并实现:
/** * 抽象处理者 */ public abstract class Handler { private final String TAG = this.getClass().getSimpleName(); //下一个节点的处理者 protected Handler nextHandler; /** * 处理请假的请求 * @param day 请假天数 */ public void handleRequest(float day) { if (day < limit()) { System.out.println(TAG + " 审批 "); } else { nextHandler.handleRequest(day); } } /** * 能审批的天数 * @return */ public abstract float limit(); }
/** * 组长 */ public class GroupLeader extends Handler { @Override public float limit() { return 1f; } }
/** * 部长 */ public class Minister extends Handler { @Override public float limit() { return 10f; } }
/** * 主管 */ public class Director extends Handler { @Override public float limit() { return 3f; } }
使用时,要将处理者连接成链状,然后从第一个节点传入请求:
public static void main(String[] args) { Handler groupLeader = new GroupLeader(); Handler director = new Director(); Handler minister = new Minister(); groupLeader.nextHandler = director; director.nextHandler = minister; groupLeader.handleRequest(5); }
以上的责任链中,发送的请求是固定的值,请求和处理者的规则是一定的。为了可以扩展更多的规则,我们可以将请求也抽象化,提供一个处理级别的方法。请求者需要判断自己的处理级别是否和请求级别相同:抽象的责任链模式
/** * 责任链模式——抽象处理者 */ public abstract class AbstractHandler { //下一个节点的处理者 public AbstractHandler nextHandler; /** * 处理请求 * @param request */ public final void handleRequest(AbstractRequest request) { if (request.getRequestLevel() == getHandleLevel()) { handle(request); } else { if (nextHandler != null) { nextHandler.handleRequest(request); } else { System.out.println("All handler can not handle this request"); } } } /** * 获取处理级别 * @return */ public abstract int getHandleLevel(); /** * 此处理者处理请求 */ protected abstract void handle(AbstractRequest request); }
/** * 责任链模式——抽象请求者 */ public abstract class AbstractRequest { //要处理的事件对象 private String content; public AbstractRequest(String content) { this.content = content; } /** * 获取要处理的事件对象 * @return */ public String getContent() { return content; } /** * 获取请求级别 * @return */ public abstract int getRequestLevel(); }
实现多种请求和处理者,需要定义每个请求和处理者的级别:
/** * 具体处理者1 */ public class Handler1 extends AbstractHandler { //此处理者的处理级别 private static final int HANDLER_LEVEL = 1; @Override public int getHandleLevel() { return HANDLER_LEVEL; } @Override protected void handle(AbstractRequest request) { System.out.println("Handler" + HANDLER_LEVEL + " handle this request, level: " + request.getRequestLevel() + " content: " + request.getContent()); } }
/** * 具体处理者2 */ public class Handler2 extends AbstractHandler { private static final int HANDLER_LEVEL = 2; @Override public int getHandleLevel() { return HANDLER_LEVEL; } @Override protected void handle(AbstractRequest request) { System.out.println("Handler" + HANDLER_LEVEL + " handle this request, level: " + request.getRequestLevel() + " content: " + request.getContent()); } }
/** * 具体处理者3 */ public class Handler3 extends AbstractHandler { private static final int HANDLER_LEVEL = 3; @Override public int getHandleLevel() { return HANDLER_LEVEL; } @Override protected void handle(AbstractRequest request) { System.out.println("Handler" + HANDLER_LEVEL + " handle this request, level: " + request.getRequestLevel() + " content: " + request.getContent()); } }
/** * 具体请求者1 */ public class Request1 extends AbstractRequest { //此请求者的请求级别 private static final int REQUEST_LEVEL = 1; public Request1(String content) { super(content); } @Override public int getRequestLevel() { return REQUEST_LEVEL; } }
/** * 具体请求者2 */ public class Request2 extends AbstractRequest { private static final int REQUEST_LEVEL = 2; public Request2(String content) { super(content); } @Override public int getRequestLevel() { return REQUEST_LEVEL; } }
/** * 具体请求者3 */ public class Request3 extends AbstractRequest { private static final int REQUEST_LEVEL = 3; public Request3(String content) { super(content); } @Override public int getRequestLevel() { return REQUEST_LEVEL; } }
使用方法相同:
public static void main(String[] args) { Handler1 handler1 = new Handler1(); Handler2 handler2 = new Handler2(); Handler3 handler3 = new Handler3(); handler1.nextHandler = handler2; handler2.nextHandler = handler3; Request1 request1 = new Request1("content1"); Request2 request2 = new Request2("content2"); Request3 request3 = new Request3("content3"); handler1.handleRequest(request1); handler1.handleRequest(request2); handler1.handleRequest(request3); }
抽象后的请求和处理者可以方便扩展更多的规则,而处理者只需要在属于自己级别范围的情况下处理请求即可。
总之,责任链模式可以让请求的发送者和处理者解偶,请求者只需要发出符合规则的请求,并明确请求的级别。单独的处理者除了要将自己无法处理的请求传给下一个处理者外,不需要关心其他处理者。责任链要求所有的处理者连接成链,可以方便地增加或删除处理者,当然,处理请求的过程需要遍历处理者,当处理者过多时,遍历可能会影响性能。

浙公网安备 33010602011771号