Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.(将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。)
职责链模式 常用在框架开发中,用来实现框架的过滤器 、拦截器 功能,让框架的使用者在不需要修改框架源码的情况下,添加新的过滤拦截功能。这也体现了之前讲到的对扩展开放、对修改关闭的设计原则。
1 责任链模式 UML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 public abstract class Handler { protected Handler successor = null ; public void setSuccessor (Handler successor) { this .successor = successor; } public abstract void handle () ; } public class HandlerA extends Handler { @Override public void handle () { boolean handled = false ; if (!handled && successor != null ) { successor.handle(); } } } public class HandlerB extends Handler { @Override public void handle () { boolean handled = false ; if (!handled && successor != null ) { successor.handle(); } } } public class HandlerChain { private Handler head = null ; private Handler tail = null ; public void addHandler (Handler handler) { handler.setSuccessor(null ); if (head == null ) { head = handler; tail = handler; return ; } tail.setSuccessor(handler); tail = handler; } public void handle () { if (head != null ) { head.handle(); } } } public static void main (String[] args) { HandlerChain chain = new HandlerChain(); chain.addHandler(new HandlerA()); chain.addHandler(new HandlerB()); chain.handle(); }
这种是最简单好理解的责任链模式的例子,每个 handler 执行完都回去执行 successor(相当于 next 指针) 的方法。这种方式需要在每个实现类中手动的调用 successor ,我们还可以做一下封装,将这部分逻辑交给父类,子类只需要控制是否需要继续执行下一个 succesor 即可。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public abstract class Handler { protected Handler successor = null ; public void setSuccessor (Handler successor) { this .successor = successor; } public final void handle () { boolean handled = doHandle(); if (successor != null && !handled) { successor.handle(); } } protected abstract boolean doHandle () ; }
将 Handler 做如上修改,在 handle() 中做链表的处理,子类只需要返回是否需要继续执行,HandlerChain 不变。
1 2 3 4 5 6 7 8 public class HandlerA extends Handler { @Override protected boolean doHandle () { boolean handled = false ; return handled; } }
当然还有一种很好理解的方式,将所有的 handler 添加到一个 List 当中,循环执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public interface IHandler { boolean handle () ; } public class HandlerA implements IHandler { @Override public boolean handle () { boolean handled = false ; return handled; } } public class HandlerChain { private List<IHandler> handlers = new ArrayList<>(); public void addHandler (IHandler handler) { this .handlers.add(handler); } public void handle () { for (IHandler handler : handlers) { boolean handled = handler.handle(); if (handled) { break ; } } } }
有些情况是需要在每一级做一些处理,可以修改一下返回,就可以实现。
2 简单实现 假如需要报销一笔费用,首先给将报销单给 部门组长 ,组长权限不够交给 部门主管 ,主管权限不够交给 经理 ,经理不够交给 老板 。这个过程就像一个责任链,我们只需要将报销单交给部门组长,具体谁报销不需要关系,我们在乎的只有结果… 责任链模式很好的将处理者与发起者解耦,避免写出成堆的 if - else 。
由于这里有统一的判断条件,那就是金额,所以将是否拦截统一交给父类,而不是子类处理拦截。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 public abstract class Leader { protected Leader superior = null ; public void setSuccessor (Leader successor) { this .superior = successor; } public final void handleRequest (int money) { if (money <= limit()) { handle(money); } else { if (superior != null ) { superior.handleRequest(money); } } } protected abstract int limit () ; protected abstract void handle (int money) ; } public class GroupLeader extends Leader { @Override protected int limit () { return 1000 ; } @Override protected void handle (int money) { System.out.println("组长批复报销" + money + "元" ); } } public class Director extends Leader { @Override protected int limit () { return 5000 ; } @Override protected void handle (int money) { System.out.println("主管批复报销" + money + "元" ); } } public class LeaderChain { private Leader head = null ; private Leader tail = null ; public void addLeader (Leader handler) { handler.setSuccessor(null ); if (head == null ) { head = handler; tail = handler; return ; } tail.setSuccessor(handler); tail = handler; } public void handleRequest (int money) { if (head != null ) { head.handleRequest(money); } } } LeaderChain chain = new LeaderChain(); chain.addLeader(new GroupLeader()); chain.addLeader(new Director()); chain.addLeader(new Manager()); chain.addLeader(new Boss()); chain.handleRequest(10000 );
3 Android 中的责任链模式
Touch 事件
事件分发(源码分析)
OkHTTP 拦截器
重点在于每个拦截器都换调用 chain.proceed(request) 调用下一个拦截器等待返回。OkHttp源码分析(二) 责任链实现篇 RealInterceptorChain
感谢
设计模式之美
《Android 源码设计模式解析与实战》
以及上文中的链接