深入了解Java设计模式之职责链模式
目录
- 定义
- 解决的问题
- 核心要点
- 类图
- 代码实现
- 抽象父类
- 执行者-三个
- 客户端
- 拓展
- 应用场景
定义 使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
文章图片
解决的问题
请求和处理分开、实现解耦、提高系统的灵活性
可以动态的调整请求的链条,增加系统灵活性
核心要点
【深入了解Java设计模式之职责链模式】职责链模式每个执行者都包含了另一个执行者的引用。如果一个对象不能处理该请求,会把请求传递给下一个执行者。
客户端需要动态的调整,执行者的上下级。
Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。
类图
文章图片
代码实现
抽象父类
/** * 处理请求的抽象类 * * @author Promsing(张有博) * @version 1.0.0 * @since 2022/9/7 - 9:29 */public abstract class Handler {//维持一个下一个执行者的引用protected Handler handler; protected void setHandler(Handler handler) {this.handler = handler; }//处理请求的抽象方法public abstract voidprocessRequest(int request); }
执行者-三个
/** *只处理数字1-10 * * @author Promsing(张有博) * @version 1.0.0 * @since 2022/9/7 - 9:31 */public class ConcreteHandlerA extends Handler{@Overridepublic void processRequest(int request) {if (request>=0 && request<10 ){System.out.println("ConcreteHandlerA已经处理完毕了"+request); return; }if (handler!=null){//下一位处理handler.processRequest(request); }}}/** * 只处理数字10-20 * * @author Promsing(张有博) * @version 1.0.0 * @since 2022/9/7 - 9:31 */public class ConcreteHandlerB extends Handler{@Overridepublic void processRequest(int request) {if (request>=10 && request<20 ){System.out.println("ConcreteHandlerB已经处理完毕了"+request); return; }if (handler!=null){//下一位处理handler.processRequest(request); }}}/** *只处理数字30+ * * @author Promsing(张有博) * @version 1.0.0 * @since 2022/9/7 - 9:31 */public class ConcreteHandlerC extends Handler{@Overridepublic void processRequest(int request) {if (request>=30 ){System.out.println("ConcreteHandlerC已经处理完毕了"+request); return; }if (handler!=null){//下一位处理handler.processRequest(request); }}}
客户端
public class Main {public static void main(String[] args) {//创建执行者Handler h1=new ConcreteHandlerA(); Handler h2=new ConcreteHandlerB(); Handler h3=new ConcreteHandlerC(); //设置向下级的顺序,可根据配置动态设置上下级h1.setHandler(h2); h2.setHandler(h3); int[] requests={8,11,23,50,7,19,28,40}; //循环处理请求,不同的数值,交给不同的执行者for (int request : requests) {h1.processRequest(request); }}}
拓展 SpringMVC中DispatchServlet使用职责链
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {HttpServletRequest processedRequest = request; //请求HandlerExecutionChain mappedHandler = null; //执行链try {ModelAndView mv = null; Exception dispatchException = null; try {// Determine handler for the current request.mappedHandler = getHandler(processedRequest); //根据请求-获得执行链//判断mappedHandler是否为空,空:404if (mappedHandler == null) {noHandlerFound(processedRequest, response); return; }// 确定当前请求的处理程序适配器HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); //职责链的前置拦截if (!mappedHandler.applyPreHandle(processedRequest, response)) {return; }//执行handler方法-controllermv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //职责链的后置拦截mappedHandler.applyPostHandle(processedRequest, response, mv); }catch (Exception ex) {dispatchException = ex; }//对结果集进行处理processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); }catch (Exception ex) {//执行完成了拦截器triggerAfterCompletion(processedRequest, response, mappedHandler, ex); }finally {//资源释放 }}
拦截器的方法
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {HandlerInterceptor[] interceptors = getInterceptors(); //获得拦截器if (!ObjectUtils.isEmpty(interceptors)) {for (int i = 0; i < interceptors.length; i++) {//循环遍历执行前置拦截HandlerInterceptor interceptor = interceptors[i]; if (!interceptor.preHandle(request, response, this.handler)) {triggerAfterCompletion(request, response, null); return false; }this.interceptorIndex = i; }}return true; } void applyPostHandle(HttpServletRequest request, HttpServletResponse response, @Nullable ModelAndView mv)throws Exception {HandlerInterceptor[] interceptors = getInterceptors(); //获得拦截器if (!ObjectUtils.isEmpty(interceptors)) {for (int i = interceptors.length - 1; i >= 0; i--) { //循环遍历执行后置拦截HandlerInterceptor interceptor = interceptors[i]; interceptor.postHandle(request, response, this.handler, mv); }} void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, @Nullable Exception ex)throws Exception {HandlerInterceptor[] interceptors = getInterceptors(); //获得拦截器if (!ObjectUtils.isEmpty(interceptors)) {for (int i = this.interceptorIndex; i >= 0; i--) {HandlerInterceptor interceptor = interceptors[i]; try {//循环遍历执行完成拦截interceptor.afterCompletion(request, response, this.handler, ex); }catch (Throwable ex2) {logger.error("HandlerInterceptor.afterCompletion threw exception", ex2); }}} }
应用场景
1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
3、可动态指定一组对象处理请求。
4、比如:JS 中的事件冒泡,JAVA WEB 中 Apache Tomcat 对 Encoding 的处理,Struts2 的拦截器,jsp servlet 的 Filter。
到此这篇关于深入了解Java设计模式之职责链模式的文章就介绍到这了,更多相关Java职责链模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
推荐阅读
- Java项目|1-1/2+1/3-1/4+1/5-...1/n 键盘获取n 结果小数;从键盘上输入n result = a+aa+aaa+aaaa+...n部分相加
- Java|Java 多线程(基础)
- Java并发编程解析 | 解析AQS基础同步器的设计与实现
- 前端面试题JavaScript篇——2022-09-08
- 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档
- 关于JavaScript中的数组方法和循环
- javascript|高效的MobX 状态管理
- javascript|uni-app 公共请求方法封装
- notepad|notepad php代码提示,Notepad++ 配置 支持jquery、html、css、javascript、php代码提示
- #|java导出功能(多个sheet页数据导出)