设计模式3-责任链模式

责任链模式是一种行为设计模式,它允许你创建一个对象链。请求沿着这条链传递,直到有一个对象处理它为止。这种模式通常用于需要以某种方式动态地决定处理请求的顺序或方式的情况。

类图:

从图中可见最大的特点是AbstractHandler它自己聚合了自己,也就是说AbstractHandler中又有一个AbstractHandler的成员属性。因为Java的实现就是用这种方式将所有Handler串成一条链。

时序图:

责任链模式包括以下主要组件:

1. 处理者(Handler)接口/抽象类
定义了处理请求的接口,通常包含一个处理请求的方法。具体的处理者(ConcreteHandler)实现该接口/抽象类,并负责处理请求,或者将请求传递给下一个处理者。

2. 具体处理者(ConcreteHandler)
实现了处理者接口/抽象类,并负责处理请求。如果它能够处理请求,则处理它;否则,将请求传递给下一个处理者。

3. 客户端(Client)
创建请求并将其发送到责任链的起始点。客户端不知道实际处理请求的对象是哪个,只需将请求发送到责任链即可。

责任链模式的优点包括:

  • 灵活性:可以动态地调整责任链的组织结构和顺序,以满足不同的需求。
  • 可扩展性:可以方便地添加新的处理者,而不影响现有的处理者和客户端代码。
  • 解耦性:请求发送者和请求处理者之间解耦,使得系统更易于维护和扩展。

一个简单的例子是,假设一个软件系统需要处理不同级别的问题(比如 Debug、Info、Warning、Error),每个级别对应一个处理者,它们按照严重程度的顺序组成责任链。当一个问题发生时,系统会将问题的级别传递给责任链的起始点,责任链会根据问题的级别逐级处理,直到找到合适的处理者。

代码:

// 定义处理请求的接口
interface Handler {void handleRequest(String level);
}// 具体处理者类
class DebugHandler implements Handler {@Overridepublic void handleRequest(String level) {if (level.equals("Debug")) {System.out.println("Debug handler is handling the request.");} else {System.out.println("Debug handler cannot handle the request, passing to the next handler.");}}
}class InfoHandler implements Handler {private Handler nextHandler;public InfoHandler(Handler nextHandler) {this.nextHandler = nextHandler;}@Overridepublic void handleRequest(String level) {if (level.equals("Info")) {System.out.println("Info handler is handling the request.");} else {System.out.println("Info handler cannot handle the request, passing to the next handler.");nextHandler.handleRequest(level);}}
}class WarningHandler implements Handler {private Handler nextHandler;public WarningHandler(Handler nextHandler) {this.nextHandler = nextHandler;}@Overridepublic void handleRequest(String level) {if (level.equals("Warning")) {System.out.println("Warning handler is handling the request.");} else {System.out.println("Warning handler cannot handle the request, passing to the next handler.");nextHandler.handleRequest(level);}}
}class ErrorHandler implements Handler {@Overridepublic void handleRequest(String level) {if (level.equals("Error")) {System.out.println("Error handler is handling the request.");} else {System.out.println("Error handler cannot handle the request, it's the end of the chain.");}}
}// 客户端类
public class Client {public static void main(String[] args) {// 创建责任链Handler debugHandler = new DebugHandler();Handler infoHandler = new InfoHandler(new WarningHandler(new ErrorHandler()));// 测试不同级别的请求debugHandler.handleRequest("Info");System.out.println("-----------------");infoHandler.handleRequest("Info");System.out.println("-----------------");infoHandler.handleRequest("Error");}
}

结果:

Debug handler cannot handle the request, passing to the next handler.
-----------------
Info handler is handling the request.
-----------------
Info handler cannot handle the request, passing to the next handler.
Warning handler cannot handle the request, passing to the next handler.
Error handler is handling the request.

应用场景:

责任链模式在实际应用中有许多使用场景,主要是在需要动态决定处理请求的顺序或方式的情况下。以下是一些常见的使用场景:

1. 日志记录
在软件系统中,日志记录是一个常见的需求。责任链模式可以用于按照日志级别(如 Debug、Info、Warning、Error)的顺序处理日志消息,每个处理者负责记录特定级别的日志,如果某个处理者无法处理某个级别的日志,则将日志传递给下一个处理者。

2. 请求过滤器
在 Web 开发中,可以使用责任链模式来实现请求过滤器链。每个过滤器负责执行一些特定的过滤逻辑,例如身份验证、日志记录、性能监控等,如果一个过滤器无法处理请求,则将请求传递给下一个过滤器。

3. 事件处理
责任链模式也可以用于事件处理,其中每个处理者负责处理特定类型的事件。例如,图形用户界面中的事件处理可以构成责任链,其中每个组件都可以处理特定类型的事件,如果一个组件无法处理事件,则将事件传递给其父组件。

4. 权限验证
在安全领域,责任链模式可以用于实现权限验证机制。每个处理者可以检查用户的权限,并决定是否允许执行特定操作,如果一个处理者无法确定用户的权限,则将请求传递给下一个处理者。

5. 订单处理
在电子商务系统中,订单处理是一个复杂的过程,涉及到库存管理、支付处理、物流等。责任链模式可以用于将订单处理流程分解为多个处理者,每个处理者负责处理特定阶段的订单处理,如果一个处理者无法处理订单,则将订单传递给下一个处理者。

这些只是责任链模式的一些常见应用场景,实际上,责任链模式可以用于许多不同的领域和情景,只要存在一系列对象,每个对象都有可能处理请求,并且请求需要按照一定顺序传递。

结论:

责任链模式使用广泛,很常见。责任链模式的关键思想是将请求发送者和请求处理者解耦,每个处理者只关心自己能否处理请求,而不关心请求的具体内容或下一个处理者是谁。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SAP MM学习笔记42 - 特殊调达流程 - 受托品(寄售)

上一章讲了 外注加工的知识。 详细可以参考如下链接。 SAP MM学习笔记41 - 特殊调达流程 - 外注加工-CSDN博客 咱们继续学习特殊调达流程。 本章主要讲受托品。 1,什么是受托品 (寄售) 仕入先提供的商品,商品是放在你公司了&a…

【十八】【C++】deque双端队列简单使用和deque底层实现探究(部分代码)

deque简单使用 在C中,双端队列(Double-Ended Queue, deque)是一种具有动态大小的序列容器,允许在两端快速插入和删除元素。与std::vector相比,std::deque提供了更加灵活的数据结构,特别是在需要频繁在序列…

Swift Combine 有序的异步操作 从入门到精通十二

Combine 系列 Swift Combine 从入门到精通一Swift Combine 发布者订阅者操作者 从入门到精通二Swift Combine 管道 从入门到精通三Swift Combine 发布者publisher的生命周期 从入门到精通四Swift Combine 操作符operations和Subjects发布者的生命周期 从入门到精通五Swift Com…

bugku 2

社工-初步收集 购买辅助--下载辅助 得到一个zip文件 里面有exe 不知道有啥用 先用dirsearch扫一下 找到/admin/login.php 随便用了个弱口令登录失败 后面看了要用wireshrak抓包 找到邮箱和pass 把pass解码 本来以为后台直接登录 但是登录失败 就是要用邮箱登录 找到账…

Vue学习笔记(三)常用指令、生命周期

Vue学习笔记(三)常用指令 vue指令:html标签上带有 v- 前缀的特殊属性,不同的指令具有不同的含义,可以实现不同的功能。 常用指令: 指令作用v-for列表渲染,遍历容器的元素或者对象的属性v-bind…

Vegeta压测工具学习与使用

Vegeta压测工具学习与使用 目标: 能够在命令行下使用Vegeta对指定API进行测试了解如何导出结果,以及能获得什么样的结果(P99,P99.9,QPS)探索能否导出其他结果,是否能够执行复杂命令或简易脚本等 时间比较紧迫,预计两到三个小时内完…

UnityShader——03图形硬件简史与可编程管线

图形硬件简史与可编程管线 GPU发展简史 GPU英文全称Graphic Processing Unit,中文翻译为“图形处理器”,在现代计算机系统中的作用变得越来越重要 20世纪六七十年代,受硬件条件的限制,图形显示器只是计算机输出的一种工具&…

C++ bfs再探迷宫游戏(五十五)【第二篇】

今天我们用bfs解决迷宫游戏。 1.再探迷宫游戏 前面我们已经接触过了迷宫游戏,并且学会了如何使用 DFS 来解决迷宫最短路问题。用 DFS 求解迷宫最短路有一个很大的缺点,需要枚举所有可能的路径,读入的地图一旦很大,可能的搜索方案…

手撕Promise

文章目录 一、Promise的初体验1.初体验——抽奖案例 二、Promise的实践练习1.实践练习——fs读取文件2.实践练习——AJAX请求 三、Promise的常见骚操作1.封装fs读取文件操作2.util.promisify方法进行promise风格转化3.封装原生的Ajax4.Promise实例对象的两个属性(1&…

鸿蒙开发系列教程(二十)--页面间动画

页面间动画 两个页面间发生跳转,一个页面消失,另一个页面出现,这时可以配置各自页面的页面转场参数实现自定义的页面转场效果 页面进入: PageTransitionEnter({type?: RouteType,duration?: number,curve?: Curve | string,…

【Android】使用Android Studio打包APK文件

文章目录 1. 新建项目2. 打包生成APK3. 安装APK 1. 新建项目 打包APK之前,首先需要新建项目,有基础的可以跳过。 无基础的可以参考:使用Android Studio运行Hello World项目 2. 打包生成APK 1.找到Build -> Generate Signed Bundle or …

C++-带你深度理解string类的常见接口

1. 为什么学习string类? C语言中,字符串是以\0结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需…