1、概念
责任链模式是为了高效,合理的处理请求。涉及到两种角色,在本文中抽象为请求方(request),响应方(response)
责任链模式非常贴近生活,在生活中,为了更高效的处理请求,我们通常制定规范的请求处理流程。为了更合理的处理请求,我们通常设置各种条件,过滤掉非法请求。
举个”高效”的示例:
例如日常公司的请假流程,有员工,组长,部长,董事长四种角色。董事长有权利给任何员工通过请假流程,但是员工基数很大,而董事长只有一人,随便一个员工请假都需要经过董事长的话,不仅效率低,而且会导致董事长很疲劳。正所谓事无巨细,人无完人。
举个”合理”的示例:
例如大型的科研机构中有些办公场所需要提供权限才能进出。让任何人进出这些办公场所会有可能会导致数据的泄密,资料丢失等等严重的后果。
2、流程图
3、UML图
4、代码
IHandler接口
/** * * @File Name: IHandler.java * @Description: 扮演处理器的角色,它只有一个方法handle * @version 1.0 * @since JDK 1.8 */ public interface IHandler { Reply handle(); }
Reply枚举类,一般都有三个值,至于这三个值变量名无所谓,表达的含义必须相同
/** * * @File Name: Reply.java * @Description: 调用handler之后的返回值,它可以理解为当前Handler对请求的处理结果 * @version 1.0 * @since JDK 1.8 */ public enum Reply { /** * 当handler返回此值时,跳过剩余的所有handler */ ACCEPT, /** * 否定,当handler返回此值时,请求无效 */ DENY, /** * 当handler返回此值时,继续执行下一个handler, */ NEUTRAL }
HandlerManager
public class HandlerManager { // 职责链 List<IHandler> handlers = new LinkedList<IHandler>(); /** * * @Title: addHandler * @Author: wrd * @Description:在职责链上添加一个handler * @param handler */ public void addHandler(IHandler handler) { this.handlers.add(handler); } /** * * @Title: removeHandler * @Author: wrd * @Description:在职责链上删除一个handler */ public void removeHandler(IHandler handler) { this.handlers.remove(handler); } // set 和 get 省略 }
HandlerImpl,可以有1到N个,可以动态添加,删除。
public class Handler1Impl implements IHandler { @Override public Reply handle() { System.out.println("Handler 1号正在执行"); return Reply.NEUTRAL; } }
Client,测试类
/** * * @File Name: Client.java * @Description: 扮演请求方 * @version 1.0 * @since JDK 1.8 */ public class Client { public static void main(String[] args) { // 职责链管理器,它的作用是添加,删除,查看Handler,等等功能 HandlerManager manager = new HandlerManager(); // 创建1号handler1,它的返回值是NEUTRAL IHandler handler1 = new Handler1Impl(); // 创建2号handler2, 它的返回值是DENY IHandler handler2 = new Handler2Impl(); // 创建3号handler3,它的返回值是Accept IHandler handler3 = new Handler3Impl(); // 添加到职责链中 List<IHandler> handlers = manager.getHandlers(); // 顺序很重要 handlers.add(handler3); handlers.add(handler2); handlers.add(handler1); // 执行职责链 chain: for (IHandler currentHandler : handlers) { Reply reply = currentHandler.handle(); switch (reply) { case NEUTRAL: { // 继续下一个循环,执行下一个handler continue; } case DENY: { // 结束当前的职责链 break chain; } case ACCEPT: { // 结束当前的职责链 // 调用response.handle(request)的方法,这里没有写 break chain; } default: break; } } } }
5、讨论
问题1:职责链模式的一些注意点
答:在使用职责链模式时,由于无法确定Handler的数量,所以一般使用LinkedList集合。
在获取handler的响应结果时,枚举类比其他方式更具优势,而且它只有三个值,分别代表否定请求,继续执行下一个handler,结束handler链。
在管理handler时,可以将HandlerManager设计为接口,提供不同的实现类。
6、示例
- Servlet的过滤器Filter。
- SpringMVC的拦截器Inteceptors。
- Logback的Filter。