第一种,双向链表的方式

具体处理者

public  class ModelHandler {private ModelHandler next;private ModelHandler last;public final ModelHandler getLast() {return last;}public final void setLast(ModelHandler last) {this.last = last;}public final ModelHandler getNext() {return next;}public final void setNext(ModelHandler next) {this.next = next;}//前置处理器protected boolean preHandle(PoJo poJo, HttpServletRequest request, HttpServletResponse response){return true;}public final void preHandlerRequest(PoJo poJo, HttpServletRequest request, HttpServletResponse response){boolean handle = preHandle(poJo, request, response);if (!handle)return;if (next!=null){next.preHandlerRequest(poJo,request,response);}}//后置处理器protected void afterHandle(PoJo poJo, HttpServletRequest request, HttpServletResponse response){}public final void afterHandleRequest(PoJo poJo, HttpServletRequest request, HttpServletResponse response){afterHandle(poJo, request, response);if (last!=null){last.afterHandleRequest(poJo,request,response);}
}

执行者

public abstract class Model implements ApplicationRunner {private ModelHandler head;//指向责任链头部的指针private  ModelHandler tail;//指向责任链尾部的指针/*** Description: 调用入口* Param: [request, response]* return: void* Date: 2021/6/17*/public final void  invoke(HttpServletRequest request, HttpServletResponse response){PoJo poJo = modelPoJo(request, response);head.preHandlerRequest(poJo,request,response);tail.afterHandleRequest(poJo,request,response);}/*** Description: 添加处理器* Param: [modelHandler]* return: void* Date: 2021/6/17*/protected final void addHandler(ModelHandler modelHandler){if (modelHandler==null)return;if (head==null){head=modelHandler;}else{modelHandler.setLast(tail);tail.setNext(modelHandler);}tail = modelHandler;}protected abstract PoJo modelPoJo(HttpServletRequest request, HttpServletResponse response);

第二种,list列表的方式

处理者

public interface ModelHandler {default boolean preHandle(PoJo poJo, HttpServletRequest request, HttpServletResponse response){return true;}default void afterHandle(PoJo poJo, HttpServletRequest request, HttpServletResponse response){}
}

执行者

public abstract class Model implements ApplicationRunner {private final List<ModelHandler> modelHandlers = new ArrayList<>();public final void invoke(HttpServletRequest request,HttpServletResponse response){PoJo poJo = modelPoJo(request, response);if (poJo==null){throw  new RuntimeException("PoJo 实例化错误,请检查!");}preInvoke(poJo,request,response);afterInvoke(poJo,request,response);}private void afterInvoke(PoJo poJo,HttpServletRequest request,HttpServletResponse response){for (int i = modelHandlers.size()-1; i>=0 ; i--) {modelHandlers.get(i).afterHandle(poJo,request,response);}}//前置执行private void preInvoke(PoJo poJo,HttpServletRequest request,HttpServletResponse response){//前置执行for (ModelHandler modelHandler : modelHandlers) {boolean preHandle = modelHandler.preHandle(poJo, request, response);if (!preHandle)break;}}protected final void addHandle(ModelHandler handler){if (handler!=null)modelHandlers.add(handler);}protected abstract PoJo modelPoJo(HttpServletRequest request, HttpServletResponse response);
}

简易 责任链的两种实现方式相关推荐

  1. 图的两种存储方式---邻接矩阵和邻接表

    图:图是一种数据结构,由顶点的有穷非空集合和顶点之间边的集合组成,表示为G(V,E),V表示为顶点的集 合,E表示为边的集合. 首先肯定是要对图进行存储,然后进行一系列的操作,下面对图的两种存储方式邻 ...

  2. a - 数据结构实验之串一:kmp简单应用_串的两种模式匹配方式(BF/KMP算法)

    串的两种模式匹配方式(BF/KMP算法) 前言 串,又称作字符串,它是由0个或者多个字符所组成的有限序列,串同样可以采用顺序存储和链式存储两种方式进行存储,在主串中查找定位子串问题(模式匹配)是串中最 ...

  3. 音频信号输入itc服务器,音频信号的两种传输方式,你知多少?

    原标题:音频信号的两种传输方式,你知多少? 前 言 音频信号有两种传输方式,即平衡式(XLR)与非平衡式(RCA).关于两种传输模式究竟孰优孰劣,这个问题长久以来都有争论.萝卜青菜各有所爱,今天我们就 ...

  4. 方向gravity_两种对齐方式,layout_gravity和gravity大不同

    原标题:两种对齐方式,layout_gravity和gravity大不同 上一期我们一起学习了LinearLayout线性布局的方向.填充模型和权重,本期来一起学习LinearLayout线性布局的对 ...

  5. sa结构组网方式_5G网络包含NSA和SA两种组网方式

    近日,江苏联通联合华为在南京摄山新城西开通NSA/SA双模共享站点,同时满足了区域内2B/2C不同应用需求. 5G网络包含NSA和SA两种组网方式,由于协议演进,终端要求,5G网络前期采用NSA组网的 ...

  6. 【Spring AOP(2)篇】原理及两种实现方式(cglibjdk动态代理)

    简介: Spring AOP(Aspect-Oriented Programming,面向切面编程)是 Spring 框架的一个重要特性,用于解耦和切割业务逻辑,是实现面向切面编程的重要手段之一.本文 ...

  7. C++中的两种绑定方式(静态绑定、动态绑定)

    两种绑定方式 静态绑定:在编译时刻,根据指针或引用变量的静态类型来决定成员函数属于哪一个类. 动态绑定:在运行时刻,根据指针或引用变量实际指向或引用的对象类型(动态类型)来确定成员函数属于哪一个类. ...

  8. (C++)string 的两种输入方式和输出方式

    注:头文件如下 #include<string> #include<cstdio> #include<iostream>using namespace std; 注 ...

  9. 三十张图片让你彻底弄明白图的两种遍历方式:DFS和BFS

    1 引言   遍历是指从某个节点出发,按照一定的的搜索路线,依次访问对数据结构中的全部节点,且每个节点仅访问一次.图的遍历.遍历过程中得到的顶点序列称为图遍历序列. 2 深度优先搜索 2.1 算法思想 ...

最新文章

  1. 在ASP.NET中使用WINDOWS模式登录SQL数据库
  2. python语言程序设计西安电子科技大学答案-徐悦甡 | 个人信息 | 西安电子科技大学个人主页...
  3. 休眠调试–查找查询的来源
  4. Unity大密度建筑场景加载解决方案
  5. C语言-字符串处理函数strcat
  6. 大数据-HDFS文件系统是什么
  7. 以setuptools版本太高为例,版本太高问题的解决方案
  8. PowerDesigner 常用配置修改
  9. @Python 程序员,如何实现狂拽酷炫的 3D 编程技术?
  10. 在CentOS4上安装JMagick
  11. JAVA TCP编程和UDP编程
  12. 配电室配套设施轨道巡检机器人及辅助监控系统
  13. Spire.PDF帮你高效搞定PDF打印
  14. JS如何判断包括IE11在内的IE浏览器
  15. WIN10系统在中国知网下载期刊封面、扉页、目录的PDF版本
  16. 一图读懂 | “数据二十条”
  17. 各类工控软件图库(组态王,威纶通,西门子,昆仑通泰等通用
  18. 计算机系统结构复习(六):Limits to ILP and SMT指令级并行的限制和同时多线程
  19. Python+pandas把多个DataFrame对象写入Excel文件中同一个工作表
  20. 7款让人惊叹的HTML5粒子动画特效

热门文章

  1. 使用 Storyboard Segue 实作 UIViewController 的切换 (实例)
  2. nginx访问日志常用变量
  3. 部署DNS split分离解析服务
  4. Tensorflow object detection API 搭建自己的目标检测模型并迁移到Android上
  5. LeetCode 463. Island Perimeter
  6. 《C和指针》——在一组字符串中查找
  7. 【AI视野·今日CV 计算机视觉论文速览 第194期】Mon, 10 May 2021
  8. ECCV2018 论文简析 Oral_1
  9. 使用 nw-builder 构建跨平台桌面应用程序
  10. ctdb main loop