前言
很多框架如mybatis,servlet的filter,dubbo,安全框架诸如Spring security、apache shiro都会用到设计模式中的责任链模式,所以学习责任链模式成为帮助你学习以上这些框架的一个好的手段之一。今天我们就来了解一下责任链模式。
定义
如果有多个对象(Handler)都有机会处理数据源(RequestSource,这里不是单纯的数据库数据源,可以是一个请求,总之是来源),责任链可以使数据的发送者和接收者解耦,数据沿着责任链传递,直到有一个对象处理了它为止。形成了一条流水线的链条,所以称之为责任链,但是不仅仅局限于链条,还可以成树形或者环形,这取决于你的业务设计。
场景
插件设计、拦截器、过滤器等一些针对切入点的特定链式处理。都可以使用责任链模式。
实现方式
实现方式常用有两种,它们的不同主要是定义处理链的顺序和结构的不同,接下来我们来看看这两种方式。
方式一
通过处理器集合来定义处理顺序。好处在于可以集中管理处理器,指责单一。非常容易理解,容易实现。缺点是如果新增处理器(Handler)势必影响已有的处理器,只能顺序执行。处理流程是这样的:
接下来用代码来实现一下此模式:
HandlerChain 负责维护调用链条的顺序,这里默认实现用List来管理Handler
public interface HandlerChain { /** * 调用handler 处理 source. * * @param requestSource the request source */ void doChain(RequestSource requestSource);}// 实现public class DefaultHandlerChain implements HandlerChain { // 当前handler指针的位置 private int pos = 0; private List<Handler> handlers = new ArrayList<>(); public void addHandler(Handler handler) { handlers.add(handler); } @Override public void doChain(RequestSource requestSource) { int size = handlers.size(); if (pos < size) { //注意对pos的处理 Handler handler = handlers.get(pos++); handler.doHandler(requestSource, this); } }}
Handler是处理链的节点抽象,是数据源(RequestSource)的具体处理者,它负责对数据的处理以及决定是否进入下一个Handler。
public interface Handler { /** * Do handler. * * @param requestSource 数据源 * @param handlerChain 传入当前的Chain进行类似递归式的调用。 */ void doHandler(RequestSource requestSource,HandlerChain handlerChain);}// 其中一个实现public class HeaderHandler implements Handler { @Override public void doHandler(RequestSource requestSource, HandlerChain handlerChain) { // 处理数据 Integer header = requestSource.getHeader(); System.out.println("header handler= " + header); //继续下一个 你可以根据条件来决定是否继续进行chain handlerChain.doChain(requestSource); }}
方式二
该方式利用链表的指针特性。这里利用了链表的一部分特点,通过在当前的Handler指定下一个Handler来作为指针,相比较上面而言,Handler更自治,在节点的处理上更加灵活。
Handler负责指针以及逻辑处理:
public interface Handler { /** * 指针指向下一个处理节点. * * @return the next */ Handler getNext(); /** * 处理具体逻辑. * * @param requestSource the request source */ void doHandler(RequestSource requestSource);}// 实现public class HeaderHandler implements Handler { private Handler next; public HeaderHandler(Handler next) { this.next = next; } @Override public Handler getNext() { return next; } @Override public void doHandler(RequestSource requestSource) { Integer header = requestSource.getHeader(); System.out.println("header = " + header); if (next != null) { next.doHandler(requestSource); } }}
总结
责任链模式在各种常见框架中非常常见。所以建议各位在对此设计模式进行认真学习。
demo地址:https://gitee.com/felord/chain-pattern.git
Original url: Access
Created at: 2019-10-09 15:34:31
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论