公用技术——设计模式15——行为型模式——职责链模式

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。
原文地址:https://www.cnblogs.com/rain144576/p/9940879.html