- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
职责链模式(Chain of Responsibility Pattern)也称为责任链模式,是一种结构型设计模式,用于构建一条对象处理请求的责任链。在这个模式中,多个对象依次处理请求,直到其中一个对象能够处理该请求为止。职责链模式将请求的发送者和接收者解耦,允许多个对象都有机会处理请求,同时可以动态地配置责任链的顺序和组成.
职责链模式的核心思想是将请求沿着一条链传递,每个处理者都可以选择处理请求或将其传递给下一个处理者。这种方式类似于实现一个处理管道,每个管道元素可以选择执行任务或将任务传递给下一个元素.
为了更好地理解职责链模式,让我们考虑一个实际的例子。审批系统。假设在一个公司中,员工可以提交报销申请,然后需要一系列审批人员逐级审批,包括直属领导、部门总监、人事部门、高层领导。每个审批人员都在自己的权限内考虑是否签字,签完之后将会继续传递给下一级审批人员。这种情况下,可以使用职责链模式来构建一个审批流程。 在这个示例中,每个审批人员都是责任链中的一个节点,他们可以选择批准或拒绝请求,并将请求传递给下一个审批人员,直到有人批准或拒绝为止.
职责链模式的结构包括以下几个关键部分: Handler(处理者):定义一个处理请求的接口,并包含一个指向下一个处理者的引用。处理者可以选择处理请求或将其传递给下一个处理者.
ConcreteHandler(具体处理者):实现处理请求的具体逻辑,如果自己无法处理请求,就将请求传递给下一个处理者.
Client(客户端):创建责任链并将请求发送到责任链的第一个处理者。客户端不需要知道责任链的具体结构,只需将请求发送给第一个处理者即可.
实现职责链模式时,通常遵循以下步骤:
定义处理请求的接口(Handler),并在接口中声明处理请求的方法.
创建具体处理者类(ConcreteHandler),实现处理请求的具体逻辑。每个具体处理者都需要包含一个指向下一个处理者的引用.
在具体处理者类中,实现处理请求的逻辑,并在必要时将请求传递给下一个处理者.
在客户端代码中创建责任链,并将请求发送给责任链的第一个处理者.
现在,让我们通过 Java 代码来实现审批系统的职责链模式.
// 1. 定义处理请求的接口
interface Approver {
void approveRequest(ExpenseRequest request);
}
// 2. 创建具体处理者类
class TeamLeader implements Approver {
private Approver nextApprover;
@Override
public void approveRequest(ExpenseRequest request) {
if (request.getAmount() <= 100) {
System.out.println("Team Leader approved the expense request.");
} else if (nextApprover != null) {
nextApprover.approveRequest(request);
}
}
public void setNextApprover(Approver nextApprover) {
this.nextApprover = nextApprover;
}
}
class Manager implements Approver {
private Approver nextApprover;
@Override
public void approveRequest(ExpenseRequest request) {
if (request.getAmount() <= 500) {
System.out.println("Manager approved the expense request.");
} else if (nextApprover != null) {
nextApprover.approveRequest(request);
}
}
public void setNextApprover(Approver nextApprover) {
this.nextApprover = nextApprover;
}
}
class FinanceDepartment implements Approver {
@Override
public void approveRequest(ExpenseRequest request) {
System.out.println("Finance Department approved the expense request.");
}
}
// 3. 客户端代码
public class Client {
public static void main(String[] args) {
Approver teamLeader = new TeamLeader();
Approver manager = new Manager();
Approver finance = new FinanceDepartment();
// 构建责任链
teamLeader.setNextApprover(manager);
manager.setNextApprover(finance);
// 提交报销请求
ExpenseRequest request1 = new ExpenseRequest("John", 80);
teamLeader.approveRequest(request1);
ExpenseRequest request2 = new ExpenseRequest("Alice", 300);
teamLeader.approveRequest(request2);
ExpenseRequest request3 = new ExpenseRequest("Bob", 800);
teamLeader.approveRequest(request3);
}
}
职责链模式在实际应用中有多种典型场景,以下是一些常见的应用.
审批流程:如报销审批、请假审批等,不同级别的审批人员构成责任链,依次处理请求.
事件处理:在图形用户界面(GUI)开发中,事件处理机制可以采用职责链模式,将事件从用户界面传递给各种控件,以便处理用户输入.
日志记录:不同级别的日志记录器可以组成责任链,根据日志级别决定是否记录日志以及如何记录.
异常处理:在程序中处理异常时,可以使用职责链模式来处理不同类型的异常,以便根据异常类型采取不同的处理策略.
权限控制:在系统中控制用户访问权限时,可以使用职责链模式来构建权限控制链,根据用户的权限级别逐级检查并授权.
HTTP请求处理:Web框架中的中间件(Middleware)可以使用职责链模式来处理HTTP请求,例如身份验证、日志记录、缓存等中间件可以依次处理请求.
优点:
松耦合:职责链模式将请求的发送者和接收者解耦,允许多个对象都有机会处理请求,使系统更加灵活.
动态配置责任链:责任链的顺序和组成可以在运行时动态配置,不需要修改代码即可调整责任链.
可扩展性:可以轻松地添加新的处理者类,扩展责任链,不会影响现有代码.
缺点:
性能问题:如果责任链过长或者处理请求的逻辑复杂,可能会导致性能问题,因为每个请求都需要遍历整个责任链.
请求未处理:如果责任链没有正确配置或者没有合适的处理者来处理请求,可能导致请求无法被处理.
难以调试:责任链模式中,请求的处理路径可能会变得不透明,难以调试和理解.
与职责链模式类似的模式包括策略模式、装饰器模式和命令模式。这些模式都有一定的相似之处,但它们各自有不同的关注点和应用场景.
策略模式(Strategy Pattern):
策略模式和职责链模式都允许动态地选择不同的对象来处理请求或任务。它们都关注于将请求发送者和接收者解耦,使系统更加灵活。策略模式关注于选择不同的算法或策略来处理特定的任务,它将不同的策略封装成独立的对象,并允许在运行时切换策略。职责链模式关注于多个对象依次处理请求,直到其中一个对象能够处理为止,每个对象都有机会处理请求.
装饰器模式(Decorator Pattern):
装饰器模式和职责链模式都允许动态地包装对象以增强其功能。它们都通过组合来实现,可以链式地将多个装饰器或处理者组合在一起。装饰器模式关注于在不改变接口的情况下增强对象的功能,通常用于为单个对象添加功能。职责链模式关注于将请求从一个对象传递到另一个对象,每个对象都可以选择处理或传递请求.
命令模式(Command Pattern):
命令模式和职责链模式都可以用于将请求的发送者和接收者解耦。它们都关注于将请求封装成对象,允许将请求传递给不同的对象。命令模式关注于将请求封装成命令对象,允许撤销和重做操作,以及延迟执行请求。职责链模式关注于多个对象依次处理请求,直到其中一个对象能够处理为止,不一定涉及命令的封装和执行.
总的来说,这些模式有一些共同之处,包括解耦请求的发送者和接收者,以及支持动态配置和组合对象。然而,它们的关注点和应用场景不同,应根据具体需求来选择合适的模式。在一些情况下,这些模式甚至可以组合使用,以实现更复杂的功能.
职责链模式是一种有用的设计模式,它可以帮助构建灵活的责任链,使多个对象能够依次处理请求。通过将请求的发送者和接收者解耦,职责链模式可以实现松耦合的设计,允许在运行时动态配置责任链的顺序和组成。然而,需要注意在设计时考虑性能问题,确保责任链不会过长或过于复杂。职责链模式在实际应用中有多种典型场景,包括审批流程、事件处理、日志记录等。希望本文能够帮助你更好地理解和应用职责链模式.
最后此篇关于软件设计模式系列之十五——职责链模式的文章就讲到这里了,如果你想了解更多关于软件设计模式系列之十五——职责链模式的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
前言 在进行Maven开发时,往往需要下载大量jar包,而由于网络不稳定等其他因素可能导致jar未下载完毕,然后保留了lastUpdated文件,导致无法更新失效的jar包。 本文分享 bat脚本,自
按字母顺序排序并不是我们花太多时间担心的事情。我们在很小的时候就学习了字母表,现在我们知道它(拉丁文)以 A 开头,然后是 B,然后是 C 等等,一直到 Z。 但是这个订单究竟存储在计算机系统中的什么
我尝试使用可分离为 2 个一维向量的二维矩阵来证明二维傅里叶变换的信号属性的可分离性。地点: f(x,y) = f(x)*f(y) 那么 F(u,v) = F(u)*F(v) 使用以下代码: % Se
我需要为几个小型sqlite数据库编写文档。想描述数据的使用方式,包括表和行说明以及示例数据。 是否可以使用MySQL Workbench?如果没有其他选择,或者我可以使用任何模板? TIA! 最佳答
我正在尝试使用旧版本(例如:1.4.5)安装 memcached,但我不知道该怎么做。 brew install memcached安装最新的。 我也试过 brew install memecache
背景 多年来,我一直使用自己的类似贝叶斯方法,根据大型且不断更新的训练数据集对来自外部来源的新项目进行分类。 每个项目都有三种类型的分类: 30 个类别,其中每个项目必须属于一个类别,且最多属于两个类
嗨,我需要确定 4 个数字是否相等。数字是 size(A,1)、size(B,1)、size(C,1) 和 size(D,1),其中,例如A = [1 2; 3 4], B=[1 2 3, 4 5 6
Wikipedia 中的文章似乎太冗长了。 我将框架理解为一组精心设计的库和工具。 Qt 框架为跨平台 GUI 提供了一组库/工具。 cocoa 框架为 Mac 做了同样的事情。 软件框架的实际定义是
我们的客户最近发现了这个网站: http://mydeco.com/3d-planner/ 它有一个非常非常奇特且组合良好的 3d CAD Web 应用程序,似乎是使用 jQuery 编写的,而不是
我们正在寻找一种独立的(非 cms)日历解决方案来显示在网络上。它可以是开源的或付费服务。 我们主要是在寻找一种在 Web 上显示日历的方法,其中包含事件发生的时间和事件的名称。如果它可以按周、月、年
我想知道与软件相关的“质量保证”和“质量科学”之间的区别。 我在Google上进行了研究,但未找到有关“质量科学”的任何信息。 最佳答案 Based on the link you have prov
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
我有一个由 2 个方程和 2 个未知数组成的系统,我想使用 MATLAB 求解,但不知道如何编程。我得到了一些有关 Gamma 分布的信息(平均值为 1.86,90% 的间隔介于 1.61 和 2.1
给定一个矩阵,其中 1 是当前子集 test = 0 0 0 0 0 0 0 0 0 0 0 0
我在组合 Matlab“数据”变量的重复元素时遇到问题。我可以使用 unique 和 sort 轻松组合这些值。 [sorted,idx] = sort(data); [~,ij] = unique(
我在做的问题中有这么一段代码,如下图。定义部分只是为了向您展示数组的大小。下面我粘贴了矢量化版本 - 它慢了 2 倍以上。为什么会这样?我知道如果矢量化需要大的临时变量,我就会发生,但(看起来)这里不
我有一个 3D 矩阵,我想将它的每个 2D 分量存储在另一个 2D 矩阵的行中,该 2D 矩阵有许多行作为 3D 矩阵的第 3 维。 我该怎么做? 最佳答案 与 permute & reshape -
如果计算机能够使用纯 JavaScript(Google V8)、C++(Windows、Mac OS 和 Linux)运行程序/软件而没有任何性能问题,是否有任何好的方法可以通过要求尽可能少尽可能从
我的团队的任务是将用于播放媒体文件的全屏、信息亭式应用程序从 Windows 迁移到嵌入式 ARM Linux(瘦客户端)。我们需要在 sd/1080p 中支持 mpeg-2 播放以及 HTML、SW
我们有数以千计的具有白色或黑色或渐变背景的产品图片。我们正在寻找可以去除图片背景的软件或服务。我们需要一款能够很好地完成这项工作的智能软件。 最佳答案 在 photoshop 中,您可以记录 Acti
我是一名优秀的程序员,十分优秀!