设计模式之职责链模式

MyBatis源码剖析 - MyBatis 插件之拦截器(Interceptor)实现原理 在上一篇文章:MyBatis 教程 - MyBatis插件(Plugins)开发 中已经介绍了如何去开发一个MyBatis 插件,本文将结合MyBatis 源码来揭秘MyBatis Plugins内部实现原理。Mybatis3 插件采用责任链模式,通过动态代理组织多个拦截器(插件),通过这些拦截器可以改变Mybatis的默认行为(诸如SQL重写之类的)。本文分析使用的MyBatis 源代码版本为3. 阅读详情

什么是职责链模式

    职责链模式是避免请求发送者与接受者耦合在一起,让多个对象都可以接受到请求,从而将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理为止。
    职责链模式包含以下几个角色:
        Handler(抽象处理者):定义处理请求的接口,一般是抽象类。由于不同的具体处理类处理请求的方式不同,因此在其中定义抽象处理请求的方法。因为每一个处理这的下家还是处理者,因此在抽象处理者中定义一个抽象处理者类型的对象作为下家的引用。
        ConcreteHandler(具体处理者):是抽象处理者的子类,实现了抽象处理者中定义的抽象方法用于处理用户请求。具体处理者有两大作用:一是处理请求,不同的具体处理者以不同的形式实现抽象处理者的方法。二是转发请求,当前处理类可将请求转发给下家。
    职责链模式可以分为纯的职责链模式和不纯的职责链模式:
        纯的职责链模式:要求具体处理者只能在两个行为中选择一个,要么承担全部责任,要么将责任转发给下家,不允许出现一个具体处理者承担了一部分或全部责任还要将责任转发给下家。
        不纯的职责链模式:允许请求被一个具体处理者处理部分或全部后在转发给下家,也可以不被任何处理者所处理。

职责链模式的优缺点

优点
  1. 一个对象无需知道是其他哪个对象处理请求,降低了系统耦合。
  2. 请求处理对象只需维护一个指向下家的的引用,简化对象的相互连接。
  3. 给对象分派职责时更加灵活,可以通过在运行时对该链进行动态增加或修改改变处理请求的职责。
  4. 增加新的处理请求时无需修改代码,符合开闭原则。
缺点
  1. 不保证每个请求都会被处理。
  2. 太长的职责链涉及更多的处理对象,会降低系统性能。
  3. 可能会造成循环调用陷入死循环。

职责链模式的应用场景

  1. 有多个对象可以处理同一个请求,具体哪个对象处理在运行时决定。
  2. 不明确接受者的情况下,向多个对象中的一个提交请求。
  3. 可动态指定一组对象处理请求,客户端可以动态创建职责链处理请求,还可以改变处理请求的顺序。

职责链模式的案例

// 请求对象
public class PurchaseRequest implements Serializable {

    private int type = 0;

    private float price = 0.0f;

    private int id = 0;

}


// 抽象处理者
public abstract class Approver {

    Approver approver;

    String name;

    public Approver(String name) {
        this.name = name;
    }

    public void setApprover(Approver approver) {
        this.approver = approver;
    }

    public abstract void processRequest(PurchaseRequest purchaseRequest);

}


// 具体处理者
public class CollegeApprover extends Approver {

    public CollegeApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() < 5000 && purchaseRequest.getPrice() <= 10000) {
            System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
        } else {
            approver.processRequest(purchaseRequest);
        }
    }
}


public class DepartmentApprover extends Approver {

    public DepartmentApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() <= 5000) {
            System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
        } else {
            approver.processRequest(purchaseRequest);
        }
    }

}


public class SchoolMasterApprover extends Approver {

    public SchoolMasterApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() > 30000) {
            System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
        } else {
            approver.processRequest(purchaseRequest);
        }
    }
}


public class ViceSchoolMasterApprover extends Approver {

    public ViceSchoolMasterApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() < 10000 && purchaseRequest.getPrice() <= 30000) {
            System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理");
        } else {
            approver.processRequest(purchaseRequest);
        }
    }
}

在这里插入图片描述

职责链模式在源码中的应用

org.apache.ibatis.plugin.InterceptorChain
// 在mybatis源码中,添加拦截器就是使用责任链模式
// pluginAll 通过这个方法可以添加定义好的拦截器实现
// 通过遍历 getInterceptors 就可以去请求每一个定义好的拦截器类
public class InterceptorChain {

  private final List<Interceptor> interceptors = new ArrayList<>();

  public Object pluginAll(Object target) {
    for (Interceptor interceptor : interceptors) {
      target = interceptor.plugin(target);
    }
    return target;
  }

  public void addInterceptor(Interceptor interceptor) {
    interceptors.add(interceptor);
  }

  public List<Interceptor> getInterceptors() {
    return Collections.unmodifiableList(interceptors);
  }

}


C++时间复杂度分析 如果想要知道一个程序运行需要花费多少时间,直接运行测试不是更简单更准确吗?何必去花精力推算复杂度!首先,这个想法没问题,确实可以直接跑出来,但这属于马后炮,无法提前预估算法的时间复杂度,而且也非常受限:1、测试结果在不同处理器上运行的结果会有很大波动2、即使在同一环境下运行,不同数据也会导致结果有很大波动所以需要一个不用具体测试就能评估程序执行效率的方法,也就是时间、空间复杂度分析方法。 阅读详情

相关推荐

STM32F103ZE驱动PMW3901光流模块,从SPI配置到数据读取的完整避坑指南

本文详细解析了STM32F103ZE驱动PMW3901光流模块的全过程,从SPI配置、硬件连接到数据读取与处理,提供了完整的避坑指南。重点介绍了SPI参数配置、初始化序列优化、运动数据滤波等关键技巧,帮助开发者快速实现精准的光流检测。

weixin_42631411的博客 514

Mybatis 插件实现原理及优化

public class InterceptorChain { private final List<Interceptor> interceptors = new ArrayList<>(); public Object pluginAll(Object target) { for (Interceptor interceptor : interceptors) { target = interceptor.plugin(target); }

Brucelwl的博客 1068

【人工智能AI】是什么?

人工智能(Artificial Intelligence),英文缩写为AI。它是研究、开发用于模拟延伸和扩展人的智能的理论方法技术及应用系统的一门新的技术科学。(百度百科)人工智能的基本原理:机器从「特定的」大量数据中总结规律,形成某些「特定的知识」,然后将这种「知识」应用到现实场景中去解决实际问题。在这个基本原理的基础上,有3个特征:1、人工智能本质上是一种工具2、人工智能技能只能解决特定的问题,而不是什么都能做3、人工智能属于归纳逻辑,可以告诉你是什么,但是不能告诉你为什么。

KJCZ.AK的博客 2万+

mybatis 开发自定义插件,你学废了吗

mybatis自定义插件 介绍 MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。比如执行前、执行后或者对SQL结果集处理、sql入参处理等,这样就可以在不修改mybatis源码的情况下对sql执行的过程或结果进行修改,实现了解耦。mybatis 是在动态代理的基础上实现的。对动态代理感兴趣的可以看下JAVA 代理模式不了解一下吗? 使用场景 如果业务中需要设置一些通用数据库操作,比如创建时间、创建人等通用字段又或者是分页操作等,这类都可...

做一个有思想的技术人 2027

【SEED Labs 2.0】V*N Tunneling Lab

本文为 SEED Labs 2.0 - V*N Tunneling Lab 的实验记录。本实验工作量较大,但难度不大,重点在于搞清是谁发给谁,走的什么路径。另外,本次实验由于网络中的设备较多,修改了环境变量方便分清哪个窗口是哪个设备。这样操作起来就方便多了。...

Chenyang的博客 6976

iTunes登录协议抓包实战:绕过反检测与TLS解密的完整方案

在软件逆向与网络协议分析中,抓包工具扮演着关键角色。代理型工具如Fiddler通过修改系统代理实现HTTPS解密,而驱动型工具如HTTPDebugger则注入进程钩取网络API,但这些实现机制往往会被具有反检测策略的客户端识别。以iTunes登录协议为例,其内置证书锁定、进程完整性与系统代理检测等防护,导致常规抓包方案失效。从工具原理出发,对比不同抓包方案的暴露面,重点介绍如何利用Fiddler通过中间人代理获取明文流量,以及使用Wireshark进行被动监听规避检测的进阶技巧,并总结常见问题排查经验,为分

weixin_28607671的博客 366

【设计模式笔记】责任链/职责链模式

一、介绍 责任链模式是一种对象的行为模式。在责任链模式里,为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。 实现方式: 使用链表的方式进行串联,将多个handler串联起来; 使用list方式,循环执行list中的每个handler; 优点: 降低耦合性,发送者,发送处理者,接收者三者进行了解耦; 简化对象,对象不需要知道链的结构; 增强了灵活性,使得增加和删除请求变得容易; 缺点: 不能保证请求一定被接收; 可能不容易观察运行时的特征,有碍于除错; 二、

yrx00go的博客 3115

立创EDA实战:基于NE555的夜间氛围呼吸灯电路设计与模式切换

本文详细介绍了使用立创EDA设计基于NE555芯片的夜间氛围呼吸灯电路。项目核心是利用NE555产生PWM信号,并通过RC充放电电路实现LED亮度的缓慢周期性变化,形成呼吸效果。文章手把手教学,涵盖从电路原理分析、元件参数计算,到在立创EDA中进行原理图绘制、PCB布局布线,直至焊接调试的完整硬件设计流程,是电子爱好者入门实战的经典项目。

weixin_42153793的博客 124

【设计模式】职责链模式(C#)

C#实现职责链模式,从POP到OOP,抽象类,最后到责任链模式+建造者模式,一步一步分析各个过程的优缺点,不断优化代码。

baidu_33146219的博客 2万+

【GB28181】wvp-GB28181-pro++ZLMediaKit编译安装国标流媒体服务器教程(Windows平台)

本文基于ZMLMediaKit+WVP-PRO在windows平台进行编译部署GB28181平台,网上教程也比较多,都大同小异,实际操作过程中容易出错的地方也比较多:redis安装无密码,mysql安装后密码的修改以及wvp数据可的创建,配置文件侧修改,尤其是和端口相关的项,再就是运行服务时各种错误需要注意,常见的错误已经做了汇总,遇到问题大家不要怕,找到报错的地方查看定位即可。

废人一枚的博客 4477

最新Python爬虫实战(入门爬虫篇)——案例20:某股票数据采集(详细爬虫思路截图+抓包动图演示+完整爬虫代码+详细注释)

本次案例针对某股票行情网的静态HTML页面,实现了全市场股票数据的全自动化爬取,覆盖了从抓包分析、请求模拟、数据解析到数据存储的完整爬虫流程,非常适合入门学习者巩固基础,核心知识点和实现要点总结如下:首先是页面分析的核心逻辑,静态HTML页面的数据爬取,核心在于通过浏览器开发者工具,完成完整的抓包分析和标签结构定位。我们不需要像动态页面那样找隐藏的API接口,只需要确认数据在主文档的HTML源码中,然后通过元素选择器,精准找到每个字段对应的标签,总结出统一的标签结构规律,就能实现批量数据提取。

努力让自己发光,对的人才能迎着光而来 19万+

设计模式Python版 职责链模式

介绍了GOF设计模式中的职责链模式,用Python实现职责链模式示例,职责链模式分类。

分享、交流、合作 1319

安装Office程序时无法安装的解决方案

本文主要介绍了安装Office程序时无法安装的解决方案,希望能对安装Office的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案 2.1 前置步骤 2.2 方法一 2.3 方法二

weixin_43178406的博客 15万+

【设计模式精讲】行为型模式之职责链模式

职责链模式(chain of responsibility pattern) 定义: 避免将一个请求的发送者与接收者耦合在一起,让多个对象都有机会处理请求.将接收请求的对象连接成一条链,并且沿着这条链传递请求,直到有一个对象能够处理它为止.在职责链模式中,多个处理器(也就是刚刚定义中说的“接收对象”)依次处理同一个请 求。一个请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再 传递给 C 处理器,以此类推,形成一个链条。

专注上位机开发、机器视觉、机器学习、嵌入式软硬件开发 1万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Java设计模式-职责链模式

职责链模式

码农日常的博客 7076

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Java设计模式之职责链模式

Java设计模式之职责链模式前言正文一、定义二、结构三、实现四、纯与不纯的职责链模式1、纯的职责链模式2、不纯的职责链模式五、职责链模式优缺点与适用环境优点缺点适用环境 前言 在系统中如果存在多个对象可以处理同一请求,则可以通过职责链模式将这些处理请求的对象连成一条链,让请求沿着该链进行传递。如果链上的对象可以处理该请求则进行处理,否则将请求转发给下家来处理。职责链模式可以将请求的发送者和接收者解...

js_tengzi的博客 408

【设计模式】职责链模式

设计模式 --职责链模式

2403_87459748的博客 1307

设计模式的应用——《职责链模式》

职责链模式,是一种行为型设计模式。它的目标在于将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。职责链设计模式常常在开发框架中使用,用来实现框架的过滤器、拦截器功能,让框架的使用者在不需要对源码进行修改的情况下,添加新的过滤拦截功能,体现了开闭原则。但具体每个框架的实现会根据实际的需求来设计。

幸运的梦之星 1305

设计模式系列/ 职责链模式

设计模式系列之 职责链模式, 以及我们使用的职责链模式有哪些角色,以及如何使用。

weixin_42373116的博客 624

设计模式-职责链模式

设计模式-职责链模式 1.问题引出 2.传统解决方案 3.传统方案解决OA 系统审批问题分析 传统方式是:接收到一个采购请求后,根据采购金额来调用对应的Approver (审批 人)完成审批。 传统方式的问题分析 : 客户端这里会使用到 分支判断(比如 switch) 来对不同的采 购请求处理, 这样就存在如下问题 (1) 如果各个级别的人员审批金额发生变化,在客户端的也需要变化 (2) 客户端必须明确的知道 有多少个审批级别和访问 这样 对一个采购请求进行处理 和 Approver (审批人) 就存

xiaotai1234的博客 303

【设计模式】职责链模式(责任链模式) 行为型模式,纯与不纯的职责链模式

职责链模式是一种行为型设计模式,用于将请求的发送者和接收者解耦,通过构建处理对象链来动态分配请求。该模式适用于多级审批、事件处理等场景,如请假审批系统可按照请假天数由不同管理者处理(经理≤5天,主管≤10天,HR>10天)。核心组件包括抽象处理者(定义处理接口和链结构)和具体处理者(实现请求处理逻辑)。模式优势在于灵活调整处理流程,支持动态增减处理节点,降低系统耦合度。典型实现包含设置后继处理者方法和请求传递机制。

weixin_44131922的博客 807

设计模式20——职责链模式

1、使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。2、职责链可简化对象的相互连接,它们仅需保持一个指向其后继者的引用,而不需保持它所有的候选接收者的引用。3、可以随时增加或修改处理一个请求的结构,增强了给对象指派职责的灵活性。

weixin_43687024的博客 2030

详解Java设计模式之职责链模式

责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。在责任链模式中,请求通过一条链传递,每个对象都有机会处理请求。当一个对象无法处理请求时,它会将请求传递给链中的下一个对象,直到找到能够处理请求的对象为止。这种方式可以动态地组织和管理对象,使得请求发送者和接收者之间解耦,提高系统的灵活性和可扩展性。职责链模式的好处。

张伟的专栏 687
上一篇: 设计模式之代理模式
下一篇: 设计模式之命令模式
geek-wmy
博客等级 码龄9年 322粉丝 126原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值