基于面向对象和递归的拦截器设计模式

news2024/9/22 19:34:24

1 定义

拦截器模式(Interceptor Pattern),是指提供一种通用的扩展机制,可以在业务操作前后提供一些切面的(Cross-Cutting)的操作。这些切面操作通常是和业务无关的,比如日志记录、性能统计、安全控制、事务处理、异常处理和编码转换等。

在功能上,拦截器模式和面向切面编程(Aspect OrientedProgramming,AOP)的思想很相似。

推荐拦截器的实现方式的原因:

  1. 一个其命名更能表达前置处理和后置处理的含义。
  2. 拦截器的添加和删除会更加灵活。

2 设计原理

在这里插入图片描述

不同于Java的动态代理是利用Java反射机制的,拦截器模式完全是利用面向对象技术的,巧妙地使用组合模式外加递归调用实现了灵活、可扩展的前置处理和后置处理。

在拦截器模式中,主要包含以下角色:

  • TargetInvocation:包含了一组Interceptor和一个Target对象,确保在Target处理请求前后,按照定义顺序调用Interceptor做前置和后置处理。
  • Target:处理请求的目标接口。
  • Interceptor:拦截器接口。
  • InterceptorImpl:拦截器实现,用来在Target处理请求前后做切面处理。

各角色之间的关系如下类图所示:
在这里插入图片描述

编码实现

创建Target接口

public interface Target{ 
    public Response execute(Request request); 
}

创建Interceptor接口

public interface Interceptor { 
    public Response intercept(TargetInvocation targetInvocation); 
}

创建TargetInvocation


public class TargetInvocation {    
    private List<Interceptor> interceptorList = new ArrayList<>();    
    private Iterator<Interceptor> interceptors;    
    private Target target; private Request request;    
    public Response invoke(){        
        if( interceptors.hasNext() ){       
            //此处是整个算法的关键,这里会递归调用invoke()        
            Interceptor interceptor = interceptors.next();      
            interceptor.intercept(this);       
        }         
        return target.execute(request);     
    }     
    public void addInterceptor(Interceptor interceptor){         
        //添加新的Interceptor到TargetInvocation中         
        interceptorList.add(interceptor);         
        interceptors = interceptorList.iterator();     
    } 
}

创建具体的Interceptor

AuditInterceptor实现如下:

public class AuditInterceptor implements Interceptor{ 
	    @Override 
	    public Response intercept(TargetInvocation targetInvocation) {                                 
	    if(targetInvocation.getTarget() == null) { 
            throw new IllegalArgumentException("Target is null"); 
         } 
         System.out.println("Audit Succeeded "); 
         return targetInvocation.invoke(); 
     } 
}

LogInterceptor实现如下:

public class LogInterceptor implements Interceptor { 
	@Override 
	public Response intercept(TargetInvocation targetInvocation) { 
			System.out.println("Logging Begin"); 
			Response response = targetInvocation.invoke(); 
			System.out.println("Logging End"); 
			return response; 
		}
 }

InterceptorDemo演示


public class InterceptorDemo { 
	public static void main(String[] args) { 
			TargetInvocation targetInvocation = new TargetInvocation(); 
			targetInvocation.addInterceptor(new LogInterceptor()); 
			targetInvocation.addInterceptor(new AuditInterceptor()); 
			targetInvocation.setRequest(new Request()); 
			targetInvocation.setTarget(request->{return new Response();});
			 targetInvocation.invoke();
	}
 }

输出结果

Logging Begin
 Audit Succeeded
  Logging End

小结

拦截器模式在开源框架中被广泛使用,例如,MVC框架Struts2的Interceptor机制正是使用该模式,只是在Struts2中Target叫Action,TargetInvocation叫ActionInvocation。在开源流程引擎Activity中也有使用该模式,其Target叫Command。在COLA框架中,同样使用拦截器模式来进行Command的前置和后置处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1938615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SciPy版本与Python和NumPy各个版本的兼容性

但是现在我用Scipy1.13.1&#xff0c;Python3.10&#xff0c;NumPy2.0.0&#xff0c;使用Scipy时会报错&#xff0c;将NumPy 版本降低为1.26.4以后&#xff0c;就没有报错了。

C++ | Leetcode C++题解之第268题丢失的数字

题目&#xff1a; 题解&#xff1a; class Solution { public:int missingNumber(vector<int>& nums) {int n nums.size();int total n * (n 1) / 2;int arrSum 0;for (int i 0; i < n; i) {arrSum nums[i];}return total - arrSum;} };

【MySQL】一些业务场景常见的查询,比如实现多表字段同步,递归查询等

目录 快速加注释多表关联查询更新多个字段循环查询子级方法1&#xff1a;递归查询方法2&#xff1a;循环查询 快速加注释 使用ALTER TABLE语句可以修改表结构&#xff0c;包括添加注释。以下是添加注释的语法&#xff1a; ALTER TABLE 表名 MODIFY COLUMN 列名 列类型 COMMEN…

【开源库学习】libodb库学习(三)

4 查询数据库 如果我们不知道我们正在寻找的对象的标识符&#xff0c;我们可以使用查询在数据库中搜索符合特定条件的对象。ODB查询功能是可选的&#xff0c;我们需要使用--generate-query ODB编译器选项显式请求生成必要的数据库支持代码。 ODB提供了一个灵活的查询API&#x…

LeetCode 热题 HOT 100 (001/100)【宇宙最简单版】

【链表】 No. 0160 相交链表 【简单】&#x1f449;力扣对应题目指路 希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; ⭐题目描述&#xff1a;两个单链表的头节点 headA 和 …

51单片机嵌入式开发:13、STC89C52RC 之 RS232与电脑通讯

STC89C52RC 之 RS232与电脑通讯 第十三节课&#xff0c;RS232与电脑通讯1 概述2 Uart介绍2.1 概述2.2 STC89C52UART介绍2.3 STC89C52 UART寄存器介绍2.4 STC89C52 UART操作 3 C51 UART总结 第十三节课&#xff0c;RS232与电脑通讯 1 概述 RS232&#xff08;Recommended Stand…

huawei USG6001v1学习----NAT和智能选路

目录 1.NAT的分类 2.智能选路 1.就近选路 2.策略路由 3.智能选路 NAT:&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09; 指网络地址转换&#xff0c;1994年提出的。NAT是用于在本地网络中使用私有地址&#xff0c;在连接互联网时转而使用全局…

Java | Leetcode Java题解之第263题丑数

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isUgly(int n) {if (n < 0) {return false;}int[] factors {2, 3, 5};for (int factor : factors) {while (n % factor 0) {n / factor;}}return n 1;} }

数学建模--优劣解距离法TOPSIS

目录 简介 TOPSIS法的基本步骤 延伸 优劣解距离法&#xff08;TOPSIS&#xff09;的历史发展和应用领域有哪些&#xff1f; 历史发展 应用领域 如何准确计算TOPSIS中的理想解&#xff08;PIS&#xff09;和负理想解&#xff08;NIS&#xff09;&#xff1f; TOPSIS方法在…

<数据集>手势识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2400张 标注数量(xml文件个数)&#xff1a;2400 标注数量(txt文件个数)&#xff1a;2400 标注类别数&#xff1a;5 标注类别名称&#xff1a;[fist, no_gesture, like, ok, palm] 序号类别名称图片数框数1fist597…

Qt中在pro中实现一些宏定义

在pro文件中利用 DEFINES 定义一些宏定义供工程整体使用。&#xff08;和在cpp/h文件文件中定义使用有点类似&#xff09;可以利用pro的中的宏定义实现一些全局的判断 pro中实现 #自定义一个变量 DEFINES "PI\"3.1415926\"" #自定义宏 DEFINES "T…

XLua原理(一)

项目中活动都是用xlua开发的&#xff0c;项目周更热修也是用xlua的hotfix特性来做的。现研究底层原理&#xff0c;对于项目性能有个更好的把控。 本文认为看到该文章的人已具备使用xlua开发的能力&#xff0c;只研究介绍下xlua的底层实现原理。 一.lua和c#交互原理 概括&…

香橙派AIpro部署边缘端夜莺监控

文章目录 硬件信息硬件简介技术路线硬件参数到手实拍接口详情图应用场景相关资源香橙派官方昇腾论坛 开箱使用准备工作上电准备启动设备开发板状态 连接设备方式一、显示器直连方式二、Micro Usb 数据线串口连接方式三、Micro Usb 数据线方式网络直连方式四、Micro Usb数据线方…

R语言画散点图-饼图-折线图-柱状图-箱线图-直方图-等高线图-曲线图-热力图-雷达图-韦恩图(二D)

R语言画散点图-饼图-折线图-柱状图-箱线图-直方图-等高线图-曲线图-热力图-雷达图-韦恩图&#xff08;二D&#xff09; 散点图示例解析效果 饼图示例解析效果 折线图示例解析效果 柱状图示例解析效果 箱线图示例解析效果 直方图示例解析效果 等高线图使用filled.contour函数示例…

Pixel6 GKI 内核编译

前言 前段时间写了一篇关于pixel4 Android内核编译编译内核的流程。 但是随着Android版本的提升Google开始推崇GKI方式发内核模式,这种模式可以方便供应商剥离内核和驱动的捆绑性&#xff0c;官方抽象出一部分接口(GKI)提供给产生使用极大便利和解耦开发复杂性。 在pixel4 And…

python-爬虫实例(1):获取京东商品评论

目录 前言 道路千万条&#xff0c;安全第一条 爬虫不谨慎&#xff0c;亲人两行泪 获取京东商品评论信息 一、实例示范 二、爬虫四步走 1.UA伪装 2.获取Url 3.发送请求 4获取响应数据进行解析并保存 总结 前言 道路千万条&#xff0c;安全第一条 爬虫不谨慎&#xff0c;亲…

【BUG】已解决:AttributeError: ‘str‘ object has no attribute ‘get‘

已解决&#xff1a;AttributeError: ‘str‘ object has no attribute ‘get‘ 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c…

JVM中的GC流程与对象晋升机制

JVM中的GC流程与对象晋升机制 1、JVM堆内存结构2、Minor GC流程3、Full GC流程4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java虚拟机&#xff08;JVM&#xff09;中&#xff0c;垃圾回收&#xff08;GC&#xff09;是自动管…

Let’s Encrypt申请证书流程(附带问题解决方式)

文章目录 前言Let’s Encrypt 和 OpenSSL的区别文章相关 正文1、安装snapd2. 使用snapd安装certbot3. 生成证书&#xff08;需要指定nginx&#xff09;5. Nginx.conf的配置 问题1、error: system does not fully support snapd原因解决方式 2、The error was: PluginError(‘Ng…

宠物医院管理系统视频介绍

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…