论坛
潜水/灌水快乐,沉淀知识,认识更多同行。
ToB圈子
加入IT圈,遇到更多同好之人。
朋友圈
看朋友圈动态,了解ToB世界。
ToB门户
了解全球最新的ToB事件
博客
Blog
排行榜
Ranklist
文库
业界最专业的IT文库,上传资料也可以赚钱
下载
分享
Share
导读
Guide
相册
Album
记录
Doing
搜索
本版
文章
帖子
ToB圈子
用户
免费入驻
产品入驻
解决方案入驻
公司入驻
案例入驻
登录
·
注册
只需一步,快速开始
账号登录
立即注册
找回密码
用户名
Email
自动登录
找回密码
密码
登录
立即注册
首页
找靠谱产品
找解决方案
找靠谱公司
找案例
找对的人
专家智库
悬赏任务
圈子
SAAS
IT评测·应用市场-qidao123.com
»
论坛
›
数据库
›
分布式数据库
›
重学设计模式-责任链模式
重学设计模式-责任链模式
前进之路
金牌会员
|
2025-1-2 04:27:10
|
显示全部楼层
|
阅读模式
楼主
主题
972
|
帖子
972
|
积分
2916
责任链模式(Chain of Responsibility Pattern)是一种举动设计模式,它通过将请求沿着链转达,使多个对象都有机会处理该请求,从而避免了请求的发送者与接收者之间的耦合关系。本文将具体介绍责任链模式的定义、优缺点、应用场景,并通过Java代码展示其实现过程。
一、责任链模式的定义
责任链模式又称为职责链模式,其核心思想是将所有请求的处理者通过前一对象记着其下一个对象的引用而连成一条链。当有请求发生时,可将请求沿着这条链转达,直到有对象处理它为止。在这种模式下,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的转达过程,因此责任链将请求的发送者和请求的处理者解耦了。
责任链模式属于对象举动型模式,它主要由以下几个角色构成:
抽象处理者(Handler):定义一个处理请求的接口,包罗抽象处理方法和一个后继毗连。
具体处理者(Concrete Handler):实现抽象处理者的处理方法,判断能否处理本次请求,如果可以处理请求则处理,否则将该请求转给它的后继者。
客户类(Client):创建处理链,并向链头的具体处理者对象提交请求,无需关心处理细节和请求的转达过程。
二、责任链模式的优缺点
优点
低落了对象之间的耦合度:该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。
增强了系统的可扩展性:可以根据需要增加新的请求处理类,满意开闭原则。
增强了给对象指派职责的灵活性:当工作流程发生变化时,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
责任链简化了对象之间的毗连:每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了利用浩繁的 if 或者 if-else 语句。
责任分担:每个类只需要处理自己该处理的工作,不该处理的转达给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
缺点
不能保证每个请求肯定被处理:由于一个请求没有明确的接收者,所以不能保证它肯定会被处理,该请求可能一直传到链的末端都得不随处理。
对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到肯定影响:遍历多个处理者会影响性能,特殊是在一些递归调用中。
责任链创建的公道性要靠客户端来保证,增加了客户端的复杂性:可能会由于责任链的错误设置而导致系统出错,如可能会造成循环调用。
三、责任链模式的应用场景
先介绍一下作者实习时用到的,抽奖需要有规则配置,抽奖前和抽奖后都需要进行规则判断,抽奖中规则采用决策树与本文无关不多做赘述,抽奖前起首要判断是否已登录,再判断是否为黑名单,再判断抽奖次数是否到达抽该奖品的要求,等等一系列判断,只要有一个判断失败就返回,这种情况用责任链模式就非常方便,且对后面的增删查改更加友爱
责任链模式在多个场景中都有广泛应用,包括但不限于:
公司事件等级制度:一切关于工程的事件必须根据事件紧张等级匹配相应职位的人员处理,如果事件紧张等级凌驾该职位设定的处理范围就需要向上级陈诉,交由上级处理。
Java过滤器:如Netty中的Pipeline和ChannelHandler,Spring Security,Spring AOP,Dubbo Filter过滤器链等。
ERP系统流程审批:如总经理、人事经理、项目经理的审批流程。
权限控制:在网关作为微服务步调的入口,拦截客户端所有的请求实现权限控制,如先判断Api接口限流、黑名单、用户会话、参数过滤等。
四、Java实现责任链模式
下面是一个具体的Java代码示例,展示了怎样实现责任链模式。
定义请求类
起首,我们需要定义一个请求类,这个请求类包罗了我们想要处理的信息。
java代码示例
public class Request {
private String message;
public Request(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
}
复制代码
定义处理器接口
接下来,我们定义一个处理器接口,它将规定处理请求的方法。
java代码示例
public interface Handler {
void setNext(Handler handler); // 设置下一个处理者
void handle(Request request); // 处理请求的方法
}
复制代码
实现具体的处理者类
我们将实现一个或多个具体的处理者类,这些类将实现Handler接口。
java代码示例
// 处理者类 A
public class ConcreteHandlerA implements Handler {
private Handler nextHandler;
@Override
public void setNext(Handler handler) {
this.nextHandler = handler;
}
@Override
public void handle(Request request) {
if (request.getMessage().equals("A")) {
System.out.println("Handler A processed request: " + request.getMessage());
} else if (nextHandler != null) {
nextHandler.handle(request);
}
}
}
// 处理者类 B
public class ConcreteHandlerB implements Handler {
private Handler nextHandler;
@Override
public void setNext(Handler handler) {
this.nextHandler = handler;
}
@Override
public void handle(Request request) {
if (request.getMessage().equals("B")) {
System.out.println("Handler B processed request: " + request.getMessage());
} else if (nextHandler != null) {
nextHandler.handle(request);
}
}
}
// 处理者类 C
public class ConcreteHandlerC implements Handler {
private Handler nextHandler;
@Override
public void setNext(Handler handler) {
this.nextHandler = handler;
}
@Override
public void handle(Request request) {
if (request.getMessage().equals("C")) {
System.out.println("Handler C processed request: " + request.getMessage());
} else if (nextHandler != null) {
nextHandler.handle(request);
}
}
}
4. 组装责任链并测试
最后,我们需要创建一个类来组合所有处理器,形成一个责任链,并通过调用handle方法测试不同的请求。
java
public class ChainOfResponsibility {
public static void main(String[] args) {
Handler handlerA = new ConcreteHandlerA();
Handler handlerB = new ConcreteHandlerB();
Handler handlerC = new ConcreteHandlerC();
// 设置责任链
handlerA.setNext(handlerB);
handlerB.setNext(handlerC);
// 测试请求
Request requestA = new Request("A");
Request requestB = new Request("B");
Request requestC = new Request("C");
Request requestD = new Request("D");
// 处理请求
handlerA.handle(requestA); // Handler A processed request: A
handlerA.handle(requestB); // Handler B processed request: B
handlerA.handle(requestC); // Handler C processed request: C
handlerA.handle(requestD); // 无任何处理
}
}
复制代码
运行上述代码,你将看到每个请求按照设置的责任链被处理。对应于请求"A"、"B"和"C"的处理结果将被打印出来,而请求"D"则未被处理。
五、责任链模式的变种与扩展
除了上述基本实现外,责任链模式还可以进行变种和扩展,以适应差异的应用场景。
带有返回值的责任链
在现实应用中,有时我们盼望责任链中的处理者能够返回处理结果。这可以通过修改Handler接口和处理者类的实现来实现。
java代码示例
// 带有返回值的请求处理接口
public interface Handler<T> {
void setNext(Handler<T> handler);
T handle(Request request);
}
// 具体的处理者类A,带有返回值
public class ConcreteHandlerA implements Handler<String> {
private Handler<String> nextHandler;
@Override
public void setNext(Handler<String> handler) {
this.nextHandler = handler;
}
@Override
public String handle(Request request) {
if (request.getMessage().equals("A")) {
return "Handler A processed request: " + request.getMessage();
} else if (nextHandler != null) {
return nextHandler.handle(request);
}
return null;
}
}
// 具体的处理者类B,带有返回值
public class ConcreteHandlerB implements Handler<String> {
private Handler<String> nextHandler;
@Override
public void setNext(Handler<String> handler) {
this.nextHandler = handler;
}
@Override
public String handle(Request request) {
if (request.getMessage().equals("B")) {
return "Handler B processed request: " + request.getMessage();
} else if (nextHandler != null) {
return nextHandler.handle(request);
}
return null;
}
}
// 具体的处理者类C,带有返回值
public class ConcreteHandlerC implements Handler<String> {
private Handler<String> nextHandler;
@Override
public void setNext(Handler<String> handler) {
this.nextHandler = handler;
}
@Override
public String handle(Request request) {
if (request.getMessage().equals("C")) {
return "Handler C processed request: " + request.getMessage();
} else if (nextHandler != null) {
return nextHandler.handle(request);
}
return null;
}
}
// 请求类,包含需要被处理的信息
public class Request {
private String message;
public Request(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
// 客户端代码,用于测试责任链模式
public class Client {
public static void main(String[] args) {
// 创建处理者实例
Handler<String> handlerA = new ConcreteHandlerA();
Handler<String> handlerB = new ConcreteHandlerB();
Handler<String> handlerC = new ConcreteHandlerC();
// 设置责任链
handlerA.setNext(handlerB);
handlerB.setNext(handlerC);
// 创建请求
Request request1 = new Request("A");
Request request2 = new Request("B");
Request request3 = new Request("C");
Request request4 = new Request("D"); // 未知请求,测试链的末尾处理
// 处理请求并打印结果
System.out.println(handlerA.handle(request1)); // 输出: Handler A processed request: A
System.out.println(handlerA.handle(request2)); // 输出: Handler B processed request: B
System.out.println(handlerA.handle(request3)); // 输出: Handler C processed request: C
System.out.println(handlerA.handle(request4)); // 输出: null(没有处理者处理这个请求)
}
}
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
本帖子中包含更多资源
您需要
登录
才可以下载或查看,没有账号?
立即注册
x
回复
使用道具
举报
0 个回复
倒序浏览
返回列表
快速回复
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
or
立即注册
本版积分规则
发表回复
回帖并转播
回帖后跳转到最后一页
发新帖
回复
前进之路
金牌会员
这个人很懒什么都没写!
楼主热帖
UWP/WinUI3 Win2D PixelShaderEffec ...
低代码平台 - 危险的赌注
Docker 基础 - 1
小小项目-博客系统 - 服务器版本 - jav ...
后台性能测试规范
Python3程序捕获Ctrl+C终止信号 ...
实用五步法教会你指标体系的设计与加工 ...
端午假期整理了仿天猫H5 APP项目vue.js ...
Fastjson反序列化
Redis常见使用场景
标签云
AI
运维
CIO
存储
服务器
快速回复
返回顶部
返回列表