Java二十三种设计模式-责任链模式(17/23)
责任链模式:实现请求处理的灵活流转
引言
在这篇博客中,我们深入探讨了责任链模式的精髓,从其定义和用途到实现方法,再到使用场景、优缺点、与其他模式的比较,以及最佳实践和替代方案,旨在指导开发者如何在适当的场景下有效运用这一模式来提高软件设计的灵活性和可维护性。
基础知识,java设计模式总体来说设计模式分为三大类:
(1)创建型模式,共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
(2)结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
(3)行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
第一部分:责任链模式概述
1.1 定义与用途
责任链模式的基本定义
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它允许将请求沿着处理者链进行传递,直到某个处理者能够处理该请求为止。
责任链模式是一种行为型设计模式,它通过将请求的发送者和接收者解耦,将这些请求沿着一条链传递,直到链上的某个节点能够处理该请求。这种模式允许系统在运行时动态地添加或修改处理请求的方式,而无需修改已有的代码。
解释为何需要责任链模式
- 解耦请求者和处理者:责任链模式使得请求的发送者不需要知道具体的处理者是谁,只需要将请求发送到链上即可。
- 动态处理请求:可以根据需要动态地添加或删除链上的处理者,或者改变它们的处理顺序。
- 灵活性和可扩展性:当需要支持多种类型的请求或处理方式时,责任链模式提供了一种灵活的解决方案。
- 简化对象的相互通信:减少了对象之间的直接交互,简化了对象间的关系。
1.2 责任链模式的组成
处理者(Handler)
- 定义:处理者是一个接口,定义了处理请求的方法和一个指向下一个处理者的引用。
- 职责:每个具体的处理者需要实现这个接口,并决定是否能够处理接收到的请求。
请求(Request)
- 定义:请求是传递给处理者的对象,通常包含一些数据和信息,描述了需要被处理的事项。
- 职责:作为处理者链中传递的信息载体。
上下文(Context)
- 定义:上下文是请求的起始点,它知道如何创建和维护处理者链。
- 职责:创建请求并将其传递给链上的首个处理者。
具体处理者(Concrete Handler)
- 定义:具体处理者实现了处理者接口,具体实现了请求处理的逻辑。
- 职责:根据请求的类型和内容决定是否处理请求,如果能够处理,则执行相应操作;否则,将请求传递给链上的下一个处理者。
角色之间的交互
- 请求创建:上下文创建请求并将其传递给链上的第一个处理者。
- 请求传递:每个处理者检查请求,决定是否能够处理它。如果能够处理,则执行操作;否则,将请求传递给链上的下一个处理者。
- 请求处理:请求沿着处理者链传递,直到被某个处理者处理。
责任链模式通过将请求的发送者和接收者解耦,提供了一种灵活的方式来处理请求,使得在不修改现有代码的情况下,可以动态地改变请求的处理方式。在下一部分中,我们将通过Java代码示例来展示责任链模式的具体实现。
第二部分:责任链模式的实现
2.1 Java实现示例
以下是使用Java语言实现责任链模式的代码示例。假设我们有一个简单的审批系统,根据不同的审批金额,需要不同级别的经理来批准。
// 处理者接口
interface Approver {void setNextApprover(Approver next);void approve(PurchaseRequest request);
}// 具体处理者:主任
class DirectorApprover implements Approver {private Approver nextApprover;@Overridepublic void setNextApprover(Approver next) {this.nextApprover = next;}@Overridepublic void approve(PurchaseRequest request) {if (request.getAmount() <= 5000) {System.out.println("Director approved: " + request);} else {if (nextApprover != null) {nextApprover.approve(request);} else {System.out.println("No more approvers in the chain.");}}}
}// 具体处理者:部门经理
class ManagerApprover implements Approver {private Approver nextApprover;@Overridepublic void setNextApprover(Approver next) {this.nextApprover = next;}@Overridepublic void approve(PurchaseRequest request) {if (request.getAmount() <= 10000) {System.out.println("Manager approved: " + request);} else {if (nextApprover != null) {nextApprover.approve(request);} else {System.out.println("No more approvers in the chain.");}}}
}// 请求类
class PurchaseRequest {private double amount;private String purpose;public PurchaseRequest(double amount, String purpose) {this.amount = amount;this.purpose = purpose;}@Overridepublic String toString() {return "PurchaseRequest{Amount: " + amount + ", Purpose: '" + purpose + "'}";}
}// 客户端代码
public class Client {public static void main(String[] args) {Approver managerApprover = new ManagerApprover();Approver directorApprover = new DirectorApprover();managerApprover.setNextApprover(directorApprover);PurchaseRequest request1 = new PurchaseRequest(7000, "Office supplies");managerApprover.approve(request1);PurchaseRequest request2 = new PurchaseRequest(15000, "Conference equipment");managerApprover.approve(request2);}
}
2.2 责任链中的角色和职责
处理者(Handler)
- 职责:定义了一个处理请求的接口,包括设置下一个处理者的方法和处理请求的方法。
请求(Request)
- 职责:封装了请求的详细信息,可以被处理者链中的任何一个处理者访问和处理。
上下文(Context)
- 职责:在本示例中,上下文由客户端代码充当,负责创建请求并启动责任链的处理过程。
具体处理者(Concrete Handler)
- 职责:实现了处理者接口,具体实现了请求处理的逻辑,包括判断请求是否在自己的处理范围内,以及将请求传递给链上的下一个处理者。
相互作用
- 设置链:客户端代码负责构建责任链,通过
setNextApprover
方法将各个处理者连接起来。 - 请求传递:请求从链的开始传递,每个处理者决定是否处理请求或将其传递给下一个处理者。
- 请求处理:请求最终被能够处理它的处理者处理,或者到达链的末端仍未被处理。
责任链模式通过定义清晰的处理者角色和请求传递机制,实现了请求的动态分发和处理。这种模式在需要灵活处理请求的场景中非常有用,尤其是在请求的处理流程可能变化的情况下。在下一部分中,我们将探讨责任链模式的使用场景。
第三部分:责任链模式的使用场景
3.1 需要灵活处理请求的场景
在软件系统中,经常会遇到需要根据不同的条件以不同方式处理请求的场景。责任链模式通过将请求的发送者和接收者解耦,提供了一种灵活处理请求的方法。
讨论在需要灵活处理请求时,责任链模式的应用:
- 多样化处理:在不同的处理者中实现不同的业务逻辑,可以根据请求的内容选择不同的处理策略。
- 易于扩展:当需要添加新的处理方式时,只需添加一个新的处理者类,并将其加入到责任链中,无需修改现有代码。
应用实例:
- 审批流程:在企业审批流程中,不同的审批级别可能需要不同角色的审批。责任链模式可以灵活地表示这种多级审批流程。
- 权限验证:在权限验证系统中,可能需要根据不同的用户角色和资源类型进行不同的权限检查。
3.2 请求处理者动态指定的场景
在某些情况下,请求的处理者可能不是预设的,而是根据运行时的条件动态确定的。责任链模式允许在运行时构建处理者链,从而动态地指定请求的处理者。
分析在请求处理者可以动态指定时,责任链模式的优势:
- 动态构建:可以根据请求的类型或内容动态地构建责任链,使得处理流程更加灵活。
- 可配置性:通过外部配置或规则引擎来定义责任链的组成和顺序,提高了系统的可配置性。
应用实例:
- 工作流引擎:在工作流引擎中,任务的处理顺序和处理者可以根据工作流的定义动态确定。
- 内容管理系统:在内容管理系统中,不同类型或不同优先级的内容可能需要不同的审核流程和审核人员。
责任链模式通过允许请求沿着链传递,直到被适当处理,提供了一种强大的方法来处理请求。这种模式在实际开发中非常有价值,尤其是在需要处理多样化请求或请求处理流程可能变化的情况下。在下一部分中,我们将讨论责任链模式的优点与缺点。
第四部分:责任链模式的优点与缺点
4.1 优点
降低耦合度
- 解耦请求者和处理者:责任链模式使得请求的发送者和接收者之间没有直接的联系,两者通过责任链进行交互,从而降低了耦合度。
提高系统的灵活性
- 动态调整处理流程:可以在运行时根据需要动态地调整处理流程,如添加、删除或重新排列处理者。
易于扩展
- 扩展新的处理者:添加新的处理者不需要修改现有代码,符合开闭原则。
简化对象交互
- 减少直接交互:减少了对象之间的直接交互,简化了对象间的关系。
支持多样化的请求处理
- 多种处理策略:允许系统支持多种不同的请求处理策略。
4.2 缺点
处理效率问题
- 性能开销:请求可能需要在多个处理者之间传递,可能会带来性能开销。
请求可能无法被处理
- 处理者缺失:如果责任链中没有处理者能够处理请求,可能会导致请求被忽略或处理失败。
调试困难
- 问题定位:在责任链中定位问题可能比较困难,特别是当链比较长或处理逻辑复杂时。
责任链的建立和管理
- 链的维护:需要管理责任链的建立和维护,确保链的正确性。
可能引起循环引用
- 循环链:如果不当使用,责任链可能导致循环引用,从而引起无限循环。
责任链模式提供了一种灵活的方式来处理请求,允许请求沿着链传递,直到被适当处理。然而,它也需要谨慎使用,以避免增加系统的复杂性和维护难度。在实际应用中,根据具体需求和场景选择是否使用责任链模式是非常重要的。在下一部分中,我们将比较责任链模式与其他设计模式,并提供一些最佳实践和建议。
第五部分:责任链模式与其他模式的比较
5.1 与命令模式的比较
命令模式
- 定义:命令模式将请求或操作封装为一个对象,允许用户使用不同的请求对客户进行参数化。
- 特点:命令模式关注于将请求封装成对象,从而允许系统使用不同的请求、队列请求或记录请求。
责任链模式
- 定义:如前所述,责任链模式通过将请求沿着链传递,直到链上的某个节点能够处理该请求。
- 特点:责任链模式关注于请求的传递和处理,允许多个对象都有机会处理请求。
对比
- 请求封装:命令模式强调请求的封装和存储,责任链模式强调请求的传递和处理。
- 处理方式:命令模式通常由调用者直接执行命令,责任链模式则由多个潜在的处理者依次尝试处理请求。
- 目的:命令模式用于支持撤销、重做等操作,责任链模式用于实现请求处理的链式传递。
5.2 与中介者模式的对比
中介者模式
- 定义:中介者模式定义了一个中介对象,用于封装一系列对象之间的交互,从而减少这些对象之间的耦合度。
- 特点:中介者模式关注于减少对象间的直接交互,通过中介者进行通信。
责任链模式
- 定义:如前所述,责任链模式允许请求沿着处理者链进行传递,直到被适当处理。
对比
- 通信方式:中介者模式通过中介者对象来转发请求和响应,责任链模式则通过链式传递请求。
- 解耦合:中介者模式通过中介者来解耦对象间的直接引用,责任链模式通过分离请求者和处理者来解耦。
- 灵活性:责任链模式提供了处理请求的灵活性,中介者模式提供了通信方式的灵活性。
责任链模式和命令模式、中介者模式都提供了处理请求的不同方法。每种模式都有其独特的用途和优势,选择使用哪种模式取决于具体的设计需求和场景。在下一部分中,我们将提供责任链模式的最佳实践和建议。
第六部分:责任链模式的最佳实践和建议
6.1 最佳实践
确保处理者链的明确终止条件
- 终止条件:确保责任链有明确的终止条件,防止请求无限循环。
保持处理者职责单一
- 单一职责原则:每个处理者应该只处理一种类型的请求,保持职责单一。
使用享元模式优化处理者
- 享元模式:如果处理者之间有共享的资源或状态,可以使用享元模式来优化内存使用。
提供灵活的链构建方式
- 灵活构建:提供灵活的方式来构建责任链,如通过配置文件或程序逻辑。
确保线程安全
- 线程安全:在多线程环境中使用责任链模式时,确保处理者是线程安全的。
避免过度复杂的责任链
- 简化设计:避免构建过于复杂或过长的责任链,以免增加系统的复杂性和降低性能。
6.2 避免滥用
避免在简单场景使用责任链模式
- 简化解决方案:对于简单的请求处理,使用责任链模式可能过于复杂,应考虑更简单的解决方案。
避免处理者之间的过度耦合
- 解耦合:保持处理者之间的松耦合,避免它们之间的依赖关系过于紧密。
避免缺乏明确的终止条件
- 明确终止:确保责任链有明确的终止条件,防止请求处理过程中的不确定性。
6.3 替代方案
使用状态模式
- 状态变化:当对象的状态变化需要改变其行为时,可以考虑使用状态模式。
使用策略模式
- 算法替换:如果需要根据不同的条件执行不同的算法或行为,策略模式可能是一个更好的选择。
使用命令模式
- 命令封装:对于需要将请求或操作封装为对象的场景,命令模式可以提供帮助。
使用中介者模式
- 减少耦合:当系统中对象之间的通信过于复杂时,中介者模式可以减少对象间的直接耦合。
责任链模式提供了一种灵活的方式来处理请求,允许请求沿着处理者链进行传递,直到被适当处理。然而,合理使用责任链模式并避免其缺点是至关重要的。了解其替代方案可以帮助开发者根据具体需求和场景选择最合适的设计模式。在实际开发中,应根据具体情况灵活运用责任链模式,以达到最佳的设计效果。
结语
责任链模式提供了一种强大的方法来处理请求,允许请求沿着处理者链进行传递,直到被适当处理。通过本文的深入分析,希望读者能够对责任链模式有更全面的理解,并在实际开发中做出合理的设计选择。
博主还写了其他Java设计模式关联文章,请各位大佬批评指正:
(一)创建型模式(5种):
Java二十三种设计模式-单例模式(1/23)
Java二十三种设计模式-工厂方法模式(2/23)
Java二十三种设计模式-抽象工厂模式(3/23)
Java二十三种设计模式-建造者模式(4/23)
Java二十三种设计模式-原型模式(5/23)
(二)结构型模式(7种):
Java二十三种设计模式-适配器模式(6/23)
Java二十三种设计模式-装饰器模式(7/23)
Java二十三种设计模式-代理模式(8/23)
Java二十三种设计模式-外观模式(9/23)
Java二十三种设计模式-桥接模式(10/23)
Java二十三种设计模式-组合模式(11/23)
Java二十三种设计模式-享元模式(12/23)
(三)行为型模式(11种):
Java二十三种设计模式-策略模式(13/23)
Java二十三种设计模式-模板方法模式(14/23)
Java二十三种设计模式-观察者模式(15/23)
Java二十三种设计模式-迭代子模式(16/23)
持续更新中......敬请关注
相关文章:

Java二十三种设计模式-责任链模式(17/23)
责任链模式:实现请求处理的灵活流转 引言 在这篇博客中,我们深入探讨了责任链模式的精髓,从其定义和用途到实现方法,再到使用场景、优缺点、与其他模式的比较,以及最佳实践和替代方案,旨在指导开发者如何…...

Electron31-ViteAdmin桌面端后台|vite5.x+electron31+element-plus管理系统Exe
原创自研Vue3Electron31ElementPlus桌面端轻量级后台管理Exe系统。 基于最新前端技术栈Vite5.x、Vue3、Electron31、ElementPlus、Vue-I18n、Echarts实战开发桌面端高颜值后台管理模板。内置4种布局模板,支持i18n国际化、动态权限路由,实现了表格、表单、…...

鸿蒙HarmonyOS实战:创建NDK工程、毕昇编译器
NDK适用场景 适合使用NDK的场景:应用涉及如下场景时,适合采用NDK开发 性能敏感的场景,如游戏、物理模拟等计算密集型场景。 需要复用已有C或C库的场景。 需要针对CPU特性进行专项定制库的场景,如Neon加速。 不建议使用NDK的场…...

网络安全-防火墙初步认识。
文章目录 1. 防火墙是什么?2. 防火墙的工作原理是什么?3. 防火墙的分类有哪些?4. 实战4.1 防火墙管理和实验介绍4.2 防火墙命令行初体验实验目标:实验步骤: 4.3 防火墙Web初体验实验目标:实验步骤ÿ…...

golang channel什么情况main会deadlock?主协程是什么?
在 Go 语言中,main 函数是程序的入口点,它运行在主协程(也称为主 goroutine)中。主协程是程序启动后自动创建的第一个 goroutine。当 main 函数执行完毕后,整个 Go 程序就会退出,无论其他 goroutine 是否仍…...

Redis之快速入门
目录 简介 什么是Redis 特点 优势 数据库对比 应用场景 安装与配置 下载 上传解压 安装gcc 编译 查看安装目录 后端启动 测试 系统服务配置 Redis数据类型 通过命令操作Redis String(字符串) Hash(哈希) List…...

mac 安装Arthas
mac安装有两种方式 1.第一步安装Arthas 第一种: curl -L https://arthas.aliyun.com/install.sh | sh 第二种jar包形式 curl -O https://arthas.aliyun.com/arthas-boot.jar个人比较推荐第一种因为运行测试成功了 第一种安装后可能会出现一些命令不符合 需…...

创客匠人老蒋:流量是个伪命题,做好这件事是打造IP最好避坑方式
怎么样做好一个创始人的IP?流量低是否可以与创客合作陪跑服务? 在老蒋创客圈第63期对话标杆直播连麦中,老蒋与受邀嘉宾【惢众身心成长家园平台】创办人王辉老师进行了一场深度且具有启发性的交流。 老蒋指出,打造IP不仅要“做自己…...

销售预测数据挖掘实战V2.0
1、概述 沃尔玛全年都会举办几次促销减价活动。这些减价活动都是在重要节假日之前进行的,其中最大的四个节假日是超级碗、劳动节、感恩节和圣诞节。包括这些节假日在内的几周在评估中的权重是非节假日周的五倍。在缺乏完整/理想历史数据的情况下,对这些…...

【K8s】Java项目部署时为什么要用k8s?
目录 重要意义一、高可用性与弹性伸缩二、简化部署与管理三、资源隔离与安全四、容器编排与服务发现 部署步骤准备工作创建 Docker 镜像将镜像推送到镜像仓库创建 Kubernetes 资源对象部署到 Kubernetes 集群 常见问题 在 Java 项目部署中使用 Kubernetes(k8s&#…...

【Python】AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘
【Python】成功解决AttributeError: module ‘PIL.Image‘ has no attribute ‘ANTIALIAS‘ 下滑即可查看博客内容 🌈 欢迎莅临我的个人主页 👈这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地!🎇 🎓 博…...

SQL注入(cookie、base64、dnslog外带、搜索型注入)
目录 COOKIE注入 BASE64注入 DNSLOG注入—注入判断 什么是泛解析? UNC路径 网上邻居 LOAD_FILE函数 搜索型注入—注入判断 本文所使用的sql注入靶场为sqli-labs-master,靶场资源文件已上传,如有需要请前往主页或以下链接下载 信安必备…...

GPT-4:揭秘人工智能新纪元
GPT-4,是OpenAI推出的最新一代语言模型,它的出现不仅在AI技术领域引起了广泛关注,更是在全球范围内掀起了一场关于人工智能未 来的热烈讨论。本文将详细探讨GPT-4的技术突破、应用前景,以及它对社会和科技发展的深远影响。 GPT-4…...

Taro 框架 React Native 开发
1、生命周期 参考:React Native组件(一)组件的生命周期_reactnative constructor介绍-CSDN博客 1.1构造函数(constructor) 1、第一个语句必须是super(props)。 2、contructor将在任意一个RN组件被加载之前优先调用,并且只会调…...

学会平衡日常编码工作与提升学习
文章目录 一、前言二、平衡工作和学习的方法和技巧2.1 设定明确的学习目标2.2 制定合理的学习计划2.3 高效工作1. 代码复用2. 模块化设计3. 单元测试与自动化测试4. 代码审查与反馈 2.4 利用碎片时间2.5 利用在线资源2.6 保持好奇心和持续学习的心态2.7 定期评估和调整2.8 保持…...

navicate premium16破解
下载链接:https://pan.baidu.com/s/1BWowOJLYchFcRMgIn-j97A?pwdvmfu 双击安装navicat160_premium_cs_x64.exe,安装完不要打开 然后断网打开NavicatCracker.exe 打开如果报病毒按照下面方法处理: 记得一定要断网,不断网…...

Kafka运行机制(一):Kafka集群启动,controller选举,生产消费流程
前置知识 Kafka基本概念https://blog.csdn.net/dxh9231028/article/details/141270920?spm1001.2014.3001.5501 1. Kafka集群启动 Kafka在启动集群中的各个broker时,broker会向controller注册自己,并且从controller节点同步集群元数据。 broker是Kaf…...

安徽医科大学:利用UKB数据库和孟德尔随机化,研究发表更轻松!
UKB数据库联合孟德尔随机化 睡眠质量和肾功能竟然与一种严重的肝病密切相关!今天,和大家分享一篇文章,这篇文章深入探讨了睡眠参数和肾功能在新发严重代谢功能障碍相关脂肪性肝病(MASLD)中的机制作用。 通过这篇文章&…...

Ubuntu安装gdb出现错误的问题解决,DNS解析错误导致的安装失败
目录 一、问题 1、错误现象 2、初步分析 二、问题分析和处理 1、进一步确定问题 2、解决dns问题 (1)查看 dns解析文件 (2)修改namesever (3)测试系统 三、问题解决 1、问题进一步分析 …...

【Redis】解析Redisson 限流器源码
Redisson 一、注解AOP 代码部分提取二、设置限流器的失效时间 一、注解AOP 代码部分提取 // 调用Reids工具类的rateLimiter 方法long number RedisUtils.rateLimiter(combineKey, rateType, count, time);redis 工具类 public class RedisUtils {private static final Redis…...

docker-harbor 私有仓库部署和管理
harbor 开源的企业级的docker仓库软件。 仓库:私有仓库(用的最多) 公有仓库。 harnor是有图形化的,页面UI展示的一个工具。操作起来很直观。 harnor每个组件都是由容器构建的,所以安装harbor必须要有docker。 doc…...

机器学习笔记二-回归
回归是统计学和机器学习中的一种基本方法,用于建模变量之间的关系,特别是用一个或多个自变量(输入变量)来预测一个因变量(输出变量)的值。回归分析广泛应用于预测、趋势分析和关联研究中。根据目标和数据的…...

判断http链接中文件是否存在
最近项目遇到需要从http请求下载文件到服务器,下载前需要判断下http中的文件是否存在。如果判断本地服务器上文件是否存在,用file.exists来判断。但是这个方法却无法判断http中文件是否存在。 如果要判断http文件是否存在,用如下代码…...

Flink CDC (session模式)
1、 # Start YARN session ./bin/yarn-session.sh --detached 2、配置文件: rest.bind-port: {{REST_PORT}} rest.address: {{NODE_IP}} execution.target: yarn-session yarn.application.id: {{YARN_APPLICATION_ID}} 3、mysql-doris.yml source:type: mysql…...

下载ISO镜像的方法 Debian、Red Hat 、CentOS、Ubuntu、Kali Linux
目录 Debian Red Hat CentOS Ubuntu Kali Linux Debian 下载步骤: 访问Debian的官方网站:Debian官网。在网站上找到“Downloads”或类似的下载链接。选择适合你的计算机架构(如amd64、i386等)的Debian版本。点击下载ISO镜像…...

想学接口测试,不知道那个工具适合?
接口测试是软件测试中的一项重要任务,它主要关注系统的不同组件之间的数据交换和通信。接口测试是一种黑盒测试方法,它可以帮助我们验证系统的功能和性能是否达到预期,并且确保不同组件之间的消息传递是正确的。在接口测试过程中,…...

干货分享 | TSMaster—RP1210模块使用指南
RP1210是由技术和维护委员会(TMC)编写的一种建议性实践。RP1210用于对重型车辆射频相关的(主要针对)电子控制单元(ECU)进行二次编程和分析。本文主要针对TSMaster—RP1210模块的操作进行详细介绍。 本文关…...

一步解决Ubuntu中无法使用git clone的问题
在网上找了很多教程都无法解决,最后用了一行命令成功解决 git config --global url."https://github.com".insteadOf git://github.com输入这行命令,之后就可以使用git clone了...

c++的时间复杂度
前言 Hello,大家好我是文宇. 最近没怎么写文章了,写个教程吧. 正文 C是一种高级编程语言,用于开发各种类型的应用程序,包括计算机科学中的算法和数据结构。在编写代码时,了解算法和数据结构的时间复杂度非常重要,因为它可以帮…...

PDF转图片 JAVA
前言 以下是一个使用 Apache PDFBox 将 PDF 文件转换为图片的封装方法。这个方法将会把 PDF 的每一页转换为一张图片,并保存到指定的目录中。 1.添加依赖 首先,你需要在项目中添加 PDFBox 的依赖。如果你使用的是 Maven,可以在 pom.xml 中添…...