1.概述
1.1 定义
职责链模式(Chain of Responsibility),使得多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个关系连成一条链,并沿着这条链传递该请求,直到有对象处理这个请求为止。
1.2 原理
发出请求的客户端并不知道哪一个对象最终会处理这个请求,这样系统的更改在不影响客户端的情况下动态的重新组织和分配任务。
2.类图
3.角色
Handler 表示抽象传递者,定义了一个处理请求的接口,并在Handler中定义了后继对象,其后继对象类型为Handler
可以在Handler中编写代码实现后继链的设置
ConcreteHandler 表示具体传递者,处理它所负责的请求,并可以访问链中下一个对象。当有请求发送过来时,如果能够
处理该请求就处理它,否则将请求转发给后继者。
Client 表示客户端,它向链中的对象提出最初的请求。
4.优缺点
4.1 优点
1.使得接收者和发送者都没有对方的明确信息,而且链中对象自己也并不知道链的结构。可简化对象的相互连接,只需要保持一个
指向其后继者的引用,而不需要保持它所有的候选者的引用,大大降低耦合度。
2.增强了给对象指派职责的灵活性。但同时要注意一个请求很可能到了末链还没有被处理,需要事先考虑周全。就比如邮寄的时候,
地址没有写对,最终无法送达。
4.2 缺点
1.对于较长的链,请求的处理可能涉及到多个处理对象,系统的性能可能会受到影响,而且在调试代码的时候不方便。 2.如果链构建的不对,可能会造成循环调用,导致系统进入死循环。
5.实例
5.1 说明
这里以在JAVA、UML和SQL中查询关键字为案例。
5.2 代码
1)抽象传递者
/** * 抽象传递者 * @author Administrator */ public abstract class SearchContext { protected SearchContext successor; public void setSuccessor(SearchContext successor) { this.successor = successor; } /** * 抽象查询关键字方法 * @param keyword */ public abstract void search(String keyword); }
2)具体传递者
/** * 具体传递者 * @author Administrator */ public class JavaSearchContext extends SearchContext{ @Override public void search(String keyword) { if(keyword.contains("Java")) { System.out.println("查询到关键字Java"); }else { //传递请求 successor.search(keyword); } } }
/** * 具体传递者 * @author Administrator */ public class SQLSearchContext extends SearchContext{ @Override public void search(String keyword) { if(keyword.contains("SQL")) { System.out.println("查询到关键字SQL"); }else { //传递请求 successor.search(keyword); } } }
/** * 具体传递者 * @author Administrator */ public class UMLSearchContext extends SearchContext{ @Override public void search(String keyword) { if(keyword.contains("UML")) { System.out.println("查询到关键字UML"); }else { //传递请求 successor.search(keyword); } } }
3)客户端
public class Client { public static void main(String[] args) { SearchContext jSearchContext = new JavaSearchContext(); SearchContext sSearchContext = new SQLSearchContext(); SearchContext uSearchContext = new UMLSearchContext(); //给JavaSearchContext设置后继者为SQLSearchContext jSearchContext.setSuccessor(sSearchContext); //给SQLSearchContext设置后继者为UMLSearchContext sSearchContext.setSuccessor(uSearchContext); String keyword = "UML和JAVA学习"; //开始查找 jSearchContext.search(keyword); } }
5.3 效果
查询到关键字UML
5.4 分析
通过setSuccessor(SearchContext successor)为具体传递者设置后继者,从而构建责任链。