1 模式动机
为了降低系统的耦合度,将事件请求者和接收者解耦,我们可以使用命令模式来设计系统。通过增加不同的命令对象,不仅可以解耦,也可以有效解决发送和接收处理速度不一样的问题。
2 模式定义
责任链模式(Chain of Responsibility Pattern):将多个对象连成一条链,沿着这条链传递请求,直到有一个对象处理它为止,使得多个对象都有机会处理该请求。
3 模式分析
Handler处理者接口:
声明处理请求的接口。
ConcreteHandler具体处理者类:
实现处理请求的接口,指定下一处理者。
Client:
调用客户。
类图如下所示:
4 实例演示
1 package com.pattern.responsibility; 2 3 public abstract class Handler { 4 public Handler successor = null; 5 6 public abstract boolean canHandle(); 7 8 public abstract void handle(); 9 10 public void handleRequest() { 11 if(canHandle()) { 12 handle(); 13 } else { 14 getSuccessor().handleRequest(); 15 } 16 } 17 18 public Handler getSuccessor() { 19 if(successor==null) { 20 successor = new EmptyHandler(); 21 } 22 return successor; 23 } 24 25 public void setSuccessor(Handler successor) { 26 this.successor = successor; 27 } 28 }
1 package com.pattern.responsibility; 2 3 public class CommonHandler extends Handler { 4 @Override 5 public boolean canHandle() { 6 // 是否可以处理请求 7 System.out.println("Common not handle..."); 8 return false; 9 } 10 11 @Override 12 public void handle() { 13 System.out.println("Common handle..."); 14 } 15 }
1 package com.pattern.responsibility; 2 public class SpecialHandler extends Handler { 3 @Override 4 public boolean canHandle() { 5 // 具体handler实现 6 System.out.println("Special not handle..."); 7 return false; 8 } 9 10 @Override 11 public void handle() { 12 System.out.println("Special handle..."); 13 } 14 }
1 package com.pattern.responsibility; 2 3 public class ExtendHandler extends Handler { 4 @Override 5 public boolean canHandle() { 6 // 是否可以处理请求 7 return true; 8 } 9 10 @Override 11 public void handle() { 12 System.out.println("Extend handle..."); 13 } 14 }
1 package com.pattern.responsibility; 2 3 public class EmptyHandler extends Handler { 4 @Override 5 public boolean canHandle() { 6 // 是否可以处理请求 7 return true; 8 } 9 10 @Override 11 public void handle() { 12 // TODO Auto-generated method stub 13 } 14 }
1 package com.pattern.responsibility; 2 3 public class Client { 4 public static void main(String args[]) { 5 CommonHandler commonHandler = new CommonHandler(); 6 SpecialHandler specialHandler = new SpecialHandler(); 7 ExtendHandler extendHandler = new ExtendHandler(); 8 9 commonHandler.setSuccessor(specialHandler); 10 specialHandler.setSuccessor(extendHandler); 11 12 commonHandler.handleRequest(); 13 } 14 }
5 纯责任链与不纯责任链
纯责任链:
1 当handler能处理请求时,停止调用下一个handler。当handler不能处理请求时,继续调用下一个handler。只能在两个行为中选择一个,一是承担责任,二是把责任推给下家。
(好比男人要么做个有责任感的人,要么做个推卸责任的人)
2 一个请求必须被某一个处理者对象接收。
例如:工厂产品的质量检查流水线,如果出现问题,就直接将产品拿出来。如果通过检查,则传递给下一个检查员。
不纯责任链:
1 承担一部分责任又把责任传到下一个处理者(好比工厂的流水线,每处理完一道工序,交给下一个人处理)。
2 一个请求可以不被任何处理者接收。
例如:工厂产品的生产流水线,每个人都会处理一部分,然后交给下一个人。
6 优缺点
优点:
1 可以灵活方便的将处理者连接成一条链,满足不同的需求。
2 将请求者与处理者解耦,提高灵活性。
缺点:
1 与if...else...缺点一样,在找到正确逻辑处理前,要遍历每一个逻辑判断,当责任链的对象过多时,会影响性能。
7 适用环境
1 有多个对象可以处理同一请求,处理请求的时机可以放在运行时确定。
8 总结
1 责任链模式最大的好处:可以根据需求组织对应的责任链处理请求,调用某个处理者即可,不用知道它内部的实现(它可以自己处理,也可以委托其它处理者处理)。
9 问题
1 为什么不将处理器组成一个List,然后按顺序处理请求?
这样请求可能被处理多次,在某些业务场景是不合适的(比如付款单发给多个付款者,则会发生多次付款)。这些场景处理者处理完毕后,不需要下一个处理者接着处理,这样就不能用列表,而是通过责任链处理,当不需要往下传递时,马上终止处理。
2 责任链模式最可能在什么场景下使用?
当业务逻辑中包含多个if、else分支,代码看上去很糟糕时,可以考虑使用责任链模式将条件判断逻辑分散到多个处理者对象中。