当前位置: 首页 > news >正文

【设计模式】责任链模式

责任链模式(Chain of Responsibility Pattern)

责任链模式是一种行为设计模式,它允许你将请求沿着处理者链进行传递,直到其中一个处理者能够处理该请求为止。这种模式使得多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。

一、责任链模式的定义

责任链模式的核心思想是将请求的处理者连成一条链,并沿着这条链传递请求,直到链中的某个处理者能够处理该请求为止。每个处理者都包含对下一个处理者的引用,如果当前处理者不能处理请求,它会将请求传递给下一个处理者。

二、责任链模式的结构

责任链模式主要包含以下几个角色:

• 抽象处理者(Handler):定义了一个处理请求的接口,通常包含一个指向下一个处理者的引用。

• 具体处理者(ConcreteHandler):实现抽象处理者接口的具体类,处理请求或将其传递给下一个处理者。

• 客户端(Client):发起请求的对象,通常不知道请求会被传递到哪个具体的处理者。

三、责任链模式的实现

以下是一个简单的实现示例:

1.抽象处理者

public abstract class Handler {protected Handler nextHandler;public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}public abstract void handleRequest(Request request);
}

2.具体处理者

public class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(Request request) {if (request.getType() == RequestType.TYPE_A) {System.out.println("ConcreteHandlerA handles request: " + request.getDescription());} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}public class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(Request request) {if (request.getType() == RequestType.TYPE_B) {System.out.println("ConcreteHandlerB handles request: " + request.getDescription());} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}public class ConcreteHandlerC extends Handler {@Overridepublic void handleRequest(Request request) {if (request.getType() == RequestType.TYPE_C) {System.out.println("ConcreteHandlerC handles request: " + request.getDescription());} else if (nextHandler != null) {nextHandler.handleRequest(request);}}
}

3.请求类

public class Request {private RequestType type;private String description;public Request(RequestType type, String description) {this.type = type;this.description = description;}public RequestType getType() {return type;}public String getDescription() {return description;}
}public enum RequestType {TYPE_A,TYPE_B,TYPE_C
}

4.客户端代码

public class ChainOfResponsibilityDemo {public static void main(String[] args) {// 创建处理者链Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();Handler handlerC = new ConcreteHandlerC();handlerA.setNextHandler(handlerB);handlerB.setNextHandler(handlerC);// 创建请求Request requestA = new Request(RequestType.TYPE_A, "Request A");Request requestB = new Request(RequestType.TYPE_B, "Request B");Request requestC = new Request(RequestType.TYPE_C, "Request C");Request requestD = new Request(RequestType.TYPE_A, "Request D");// 处理请求handlerA.handleRequest(requestA);handlerA.handleRequest(requestB);handlerA.handleRequest(requestC);handlerA.handleRequest(requestD);}
}

四、运行效果

运行上述代码后,输出如下:

ConcreteHandlerA handles request: Request A
ConcreteHandlerB handles request: Request B
ConcreteHandlerC handles request: Request C
ConcreteHandlerA handles request: Request D

五、责任链模式的优点

• 降低耦合度:

• 请求的发送者和接收者之间没有直接的耦合关系,增加了系统的灵活性。

• 增强扩展性:

• 可以动态地添加或修改处理者的顺序,而无需修改客户端代码。

• 简化对象结构:

• 避免了复杂的条件语句,使代码更加清晰和易于维护。

六、责任链模式的缺点

• 性能问题:

• 如果链过长,可能会导致请求处理的延迟增加。

• 调试困难:

• 由于请求的处理路径可能不明确,调试时可能需要跟踪整个链。

• 无默认处理:

• 如果链中没有处理者能够处理请求,请求可能会被忽略,需要额外的机制来处理这种情况。

七、责任链模式的应用场景

• 多级审批流程:

• 在多级审批系统中,每个审批级别可以作为一个处理者,请求沿着审批链传递,直到某个级别批准或拒绝。

• 日志处理:

• 在日志系统中,不同级别的日志可以由不同的处理者处理,请求沿着日志链传递,直到某个处理者处理日志。

• 事件处理:

• 在事件驱动的系统中,事件可以沿着处理者链传递,直到某个处理者处理事件。

八、总结

责任链模式是一种非常实用的设计模式,通过将请求的处理者连成一条链,实现了请求的灵活传递和处理。通过合理使用责任链模式,可以降低系统的耦合度,增强系统的扩展性,同时避免使用复杂的条件语句。

// 责任链模式static class Solution_20250529213945_6080a9ac877d41a3a0812221e07a4754 {static public abstract class Handler {protected Handler nextHandler;public void setNextHandler(Handler nextHandler) {this.nextHandler = nextHandler;}public abstract void handleRequest(Request request);}static public class ConcreteHandlerA extends Handler {@Overridepublic void handleRequest(Request request) {if (request.getType() == RequestType.TYPE_A) {System.out.println("ConcreteHandlerA handles request: " + request.getDescription());} else if (nextHandler != null) {nextHandler.handleRequest(request);}}}static public class ConcreteHandlerB extends Handler {@Overridepublic void handleRequest(Request request) {if (request.getType() == RequestType.TYPE_B) {System.out.println("ConcreteHandlerB handles request: " + request.getDescription());} else if (nextHandler != null) {nextHandler.handleRequest(request);}}}static public class ConcreteHandlerC extends Handler {@Overridepublic void handleRequest(Request request) {if (request.getType() == RequestType.TYPE_C) {System.out.println("ConcreteHandlerC handles request: " + request.getDescription());} else if (nextHandler != null) {nextHandler.handleRequest(request);}}}static public class Request {private RequestType type;private String description;public Request(RequestType type, String description) {this.type = type;this.description = description;}public RequestType getType() {return type;}public String getDescription() {return description;}}static public enum RequestType {TYPE_A,TYPE_B,TYPE_C}public static void main(String[] args) {// 创建处理者链Handler handlerA = new ConcreteHandlerA();Handler handlerB = new ConcreteHandlerB();Handler handlerC = new ConcreteHandlerC();handlerA.setNextHandler(handlerB);handlerB.setNextHandler(handlerC);// 创建请求Request requestA = new Request(RequestType.TYPE_A, "Request A");Request requestB = new Request(RequestType.TYPE_B, "Request B");Request requestC = new Request(RequestType.TYPE_C, "Request C");Request requestD = new Request(RequestType.TYPE_A, "Request D");// 处理请求handlerA.handleRequest(requestA);handlerA.handleRequest(requestB);handlerA.handleRequest(requestC);handlerA.handleRequest(requestD);}}
http://www.xdnf.cn/news/728659.html

相关文章:

  • Scratch节日 | 龙舟比赛 | 端午节
  • 历年南京大学计算机保研上机真题
  • 信息化项目验收测试:MES 系统验收测试的测试重点
  • 海思 35XX MIPI读取YUV422
  • USB MSC SCCI
  • 力扣HOT100之动态规划:322. 零钱兑换
  • web自动化-Selenium、Playwright、Robot Framework等自动化框架使用场景优劣对比
  • 拉普拉斯噪声
  • eBest智能价格引擎系统 助力屈臣氏饮料落地「价格大脑」+「智慧通路」数字基建​
  • 医疗IT系统绝缘监测及故障定位,绝缘监测技术在医院关键区域的应用
  • t015-预报名管理系统设计与实现 【含源码!!!】
  • 【请关注】各类数据库优化,抓大重点整改,快速优化空间mysql,Oracle,Neo4j等
  • Python打卡第40天
  • 开发效率提升小技巧:快速提取图标资源的解决方案
  • Unity 中实现首尾无限循环的 ListView
  • 设计模式之简单工厂模式
  • 前端面试准备-3
  • openssl-aes-ctr使用openmp加速
  • Java大师成长计划之第35天:未来展望与个人总结
  • shell编程笔记
  • 预处理深入详解:预定义符号、宏、命名约定、命令行定义、条件编译、头文件的包含
  • 【大模型】情绪对话模型项目研发
  • C++继承与构造函数调用详解
  • flash写失败分析
  • Linux系统编程收尾(35)
  • 【C/C++】cmake实现Release版本禁用调试接口技巧
  • [定昌linux开发板]启用用户唯一性限制
  • Android全局网络监控最佳实践(Kotlin实现)
  • 从Java的Jvm的角度解释一下为什么String不可变?
  • Spring Boot3.4.1 集成redis