一、前言
责任链模式(Chain of Responsibility Pattern)是一种行为设计模式,它允许你将请求沿着处理者链进行发送,直至其中一个处理者对其进行处理。这种模式可以解耦请求的发送者和接收者,增加或修改处理者时不需要改变客户端代码,提高了系统的灵活性和可维护性。
在Java中实现责任链模式,首先需要定义一个处理器。处理器可以是抽象类,也可以是接口。处理器如果是抽象类,需要持有对下一个处理器的引用。处理器如果是接口,处理器的实现处理者需要持有对下一个处理器的引用。 处理者需要实现处理器方法,在处理请求时,要么处理它,要么将请求转发给链中的下一个处理器。(链式调用)
二、具体实现
1、审批流程案例(处理器是抽象类)
请假 领导审批;报销 财务审批;转正 人事审批。
审批接口:
/**
* @Description: 审批接口
* @Date: 2025-01-06 9:30
* @Author: gaoyufei
**/
public abstract class ApproveInterface {
protected ApproveInterface nextApproveInterface;
public void setNextApproveInterface(ApproveInterface nextApproveInterface){
this.nextApproveInterface=nextApproveInterface;
}
public abstract void approve(String context);
}
领导审批:
/**
* @Description: 领导
* @Date: 2025-01-06 9:35
* @Author: gaoyufei
**/
public class Leader extends ApproveInterface {
@Override
public void approve(String context) {
if("请假".equals(context)){
System.out.println("领导已审批请假");
}else if (nextApproveInterface!=null){
nextApproveInterface.approve(context);
}
}
}
财务审批:
/**
* @Description: 财务
* @Date: 2025-01-06 9:38
* @Author: gaoyufei
**/
public class Finance extends ApproveInterface{
@Override
public void approve(String context) {
if("报销".equals(context)){
System.out.println("财务已审批报销");
}else if(nextApproveInterface!=null){
nextApproveInterface.approve(context);
}
}
}
人事审批:
/**
* @Description: 人事
* @Date: 2025-01-06 9:40
* @Author: gaoyufei
**/
public class HR extends ApproveInterface {
@Override
public void approve(String context) {
if("转正".equals(context)){
System.out.println("人事已审批转正");
}else if (nextApproveInterface!=null){
nextApproveInterface.approve(context);
}
}
}
员工发起审批:
/**
* @Description: 员工
* @Date: 2025-01-06 9:44
* @Author: gaoyufei
**/
public class Employee {
public static void main(String[] args) {
ApproveInterface leader=new Leader();//领导
ApproveInterface finance=new Finance();//财务
ApproveInterface hr=new HR();//人事
leader.setNextApproveInterface(finance);
finance.setNextApproveInterface(hr);
// leader.approve("请假");
// leader.approve("报销");
leader.approve("转正");
}
}
2、请求拦截案例(处理器是抽象类)
无token 不可以访问;有token 可以访问。
请求接口:
/**
* @Description: 请求接口
* @Date: 2025-01-06 9:50
* @Author: gaoyufei
**/
public abstract class Request {
protected Request nextRequest;
public void setNextRequest(Request nextRequest){
this.nextRequest=nextRequest;
}
public abstract void handeRequest(String token);
}
无token请求流程:
import org.springframework.util.StringUtils;
/**
* @Description: 无token请求
* @Date: 2025-01-06 9:53
* @Author: gaoyufei
**/
public class NoTokenRequest extends Request{
@Override
public void handeRequest(String token) {
if(StringUtils.isEmpty(token)){
System.out.println("不可以访问");
}else if(nextRequest!=null){
nextRequest.handeRequest(token);
}
}
}
有token请求流程:
import org.springframework.util.StringUtils;
/**
* @Description: 有token请求
* @Date: 2025-01-06 9:53
* @Author: gaoyufei
**/
public class HaveTokenRequest extends Request{
@Override
public void handeRequest(String token) {
if(StringUtils.hasText(token)){
System.out.println("可以访问");
}else if(nextRequest!=null){
nextRequest.handeRequest(token);
}
}
}
请求构建发送:
/**
* @Description: 请求构建发送
* @Date: 2025-01-06 9:57
* @Author: gaoyufei
**/
public class RequestBuildPublish {
public static void main(String[] args) {
Request noTokenRequest=new NoTokenRequest();
Request haveTokenRequest=new HaveTokenRequest();
noTokenRequest.setNextRequest(haveTokenRequest);
noTokenRequest.handeRequest(null);
// noTokenRequest.handeRequest("123");
}
}
2、请求拦截案例(处理器是接口)
无token 不可以访问;有token 可以访问。
请求接口:
/**
* @Description: 请求接口
* @Date: 2025-01-08 8:48
* @Author: gaoyufei
**/
public interface Request {
void setNextRequest(Request nextRequest);
void handeRequest(String token);
}
无token请求流程:
import org.springframework.util.StringUtils;
/**
* @Description: 处理没token的请求
* @Date: 2025-01-08 8:50
* @Author: gaoyufei
**/
public class NoTokenRequest implements Request{
private Request nextRequest;
@Override
public void setNextRequest(Request nextRequest) {
this.nextRequest=nextRequest;
}
@Override
public void handeRequest(String token) {
if(StringUtils.isEmpty(token)){
System.out.println("不可以访问");
}else if(this.nextRequest!=null){
this.nextRequest.handeRequest(token);
}
}
}
有token请求流程:
import org.springframework.util.StringUtils;
/**
* @Description: 处理有token的请求
* @Date: 2025-01-08 8:53
* @Author: gaoyufei
**/
public class HaveTokenRequest implements Request{
private Request nextRequest;
@Override
public void setNextRequest(Request nextRequest) {
this.nextRequest=nextRequest;
}
@Override
public void handeRequest(String token) {
if(StringUtils.hasText(token)){
System.out.println("可以访问");
}else if(this.nextRequest!=null){
this.nextRequest.handeRequest(token);
}
}
}
请求构建发送:
/**
* @Description: 构建请求和发送请求
* @Date: 2025-01-08 8:55
* @Author: gaoyufei
**/
public class RequestBuildPublish {
public static void main(String[] args) {
Request noTokenRequest=new NoTokenRequest();
Request haveTokenRequest=new HaveTokenRequest();
noTokenRequest.setNextRequest(haveTokenRequest);
// noTokenRequest.handeRequest("");
noTokenRequest.handeRequest("123");
}
}