基于SpringBoot实现责任链模式进行参数校验等处理

概念:

责任链模式是一种行为设计模式,它允许多个对象都有机会处理请求,而不是将请求发送给一个处理者。每个处理者都包含对下一个处理者的引用,形成一个链条。请求沿着这条链传递,直到有一个处理者处理它为止。

使用场景:

  1. 多个对象可以处理同一请求: 当一个请求可以被多个对象中的一个处理,而不确定哪个对象会处理,就可以使用责任链模式。
  2. 请求的发送者和接收者解耦: 发送者不需要知道处理请求的具体对象,只需将请求发送给第一个处理者。接收者也不需要知道请求的发送者是谁,只需处理请求即可。
  3. 动态组合处理者: 可以动态地组合和拆解处理者链。通过增加或移除处理者,可以灵活地调整系统的处理流程。
  4. 避免请求发送者与接收者耦合: 请求发送者无需知道处理请求的具体处理者,从而降低了系统的耦合度。
  5. 处理请求的对象集合可能会变动: 处理者链可以动态地调整,适用于对象集合可能变动的情况。

缺点:

  1. 性能问题: 因为责任链的请求可能被多个处理者依次处理,直到找到合适的处理者为止,可能会导致一定的性能开销。
  2. 请求可能无法被处理: 如果责任链没有被正确配置,或者存在漏洞,可能导致请求无法被处理。
  3. 可能过于灵活: 过度使用责任链模式可能导致系统变得过于灵活,难以理解和维护。

建议:

其实看了以上缺点之后我们可以发现,对于一些不必要的场景我们尽量还是不要去使用责任链模式来给系统增加复杂度,对于后期接手项目的同学是相当的难以维护及理解,当然这里的同学指的是像我这种菜鸡程序员

案例Demo:

下面我就基于请求参数处理的需求来实现一个简单的Spingboot下开发的一个Demo案例,我处理过程中是对对象中的参数count进行规则判断进行加减

第一步是先创建出责任链处理的接口和请求参数实体对象

java 复制代码
/**责任链节点的接口
 * @Author duJi
 * @Date 2023/12/06
 */
public interface Handler  {
    /**
     * 节点处理请求接口
     * @param request
     */
    void handleRequest(HandlerRequest request);

    /**
     * 设置下一个节点处理者
     * @param nextHandler
     */
    void setNextHandler(Handler nextHandler);
}
java 复制代码
/** 请求参数实体
 * @Author duJi
 * @Date 2023/12/06
 */
public class HandlerRequest {
    private Integer count;

    public HandlerRequest(Integer count) {
        this.count = count;
    }

    public HandlerRequest() {
    }

    public Integer getCount() {
        return count;
    }

    public void setContent(Integer count) {
        this.count = count;
    }
}

第二步则是根据业务去定义相对应的处理接口实现类

java 复制代码
@Slf4j
public class FirstHandler implements Handler {
    private Handler handler;
    @Override
    public void handleRequest(HandlerRequest request) {
        //自身业务处理
        log.info("first handler");
        if (request.getCount() <= 2) {
            request.setContent(request.getCount() + 1);
        }
        //判断是否有下一处理节点
        if (Objects.nonNull(handler)){
            log.info("next handler");
            handler.handleRequest(request);
        }
    }

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.handler = nextHandler;
    }
}
java 复制代码
@Slf4j
public class SecondHandler implements Handler {
    private Handler handler;
    @Override
    public void handleRequest(HandlerRequest request) {
        //自身业务处理
        log.info("second handler");
        if (request.getCount() > 2) {
            request.setContent(request.getCount() + 1);
        }
        //判断是否有下一处理节点
        if (Objects.nonNull(handler)){
            log.info("next handler");
            handler.handleRequest(request);
        }
    }

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.handler = nextHandler;
    }
}
java 复制代码
@Slf4j
public class ThirdHandler implements Handler {
    private Handler handler;
    @Override
    public void handleRequest(HandlerRequest request) {
        //自身业务处理
        log.info("third handler");
        if (request.getCount() < 5) {
            request.setContent(request.getCount() - 1);
        }
        //判断是否有下一处理节点
        if (Objects.nonNull(handler)){
            log.info("next handler");
            handler.handleRequest(request);
        }
    }

    @Override
    public void setNextHandler(Handler nextHandler) {
        this.handler = nextHandler;
    }
}

第三步便是最关键的一步,编写责任链配置中心去管理我们需要的处理规则实现类

java 复制代码
/**责任链配置管理中心
 * @Author duJi
 * @Date 2023/12/06
 */
@Configuration
public class ChainConfig {

    @Bean
    public Handler chain() {
        FirstHandler firstHandler = new FirstHandler();
        SecondHandler secondHandler = new SecondHandler();
        ThirdHandler thirdHandler = new ThirdHandler();
        //这里填写顺序没有强制要求
        firstHandler.setNextHandler(secondHandler);
        secondHandler.setNextHandler(thirdHandler);

        return firstHandler;
    }
}

最后便是我们的测试接口了

java 复制代码
/** 责任链测试接口
 * @Author duJi
 * @Date 2023/12/06
 */
@Slf4j
@RestController
@Api(tags = "责任链测试接口")
@RequestMapping("/responsibility")
public class HandlerController {

    @Resource
    private Handler handler;

    @ApiOperation("测试接口")
    @GetMapping("/test")
    public void handleRequest(){
        HandlerRequest request = new HandlerRequest(1);
        handler.handleRequest(request);
        log.info("success , count : "+request.getCount());
    }
}

测试结果

注意

这里测试结果是没问题的,这里需要大家注意下,我的这个Demo里的handler实现是在配置中心中手动new创建出来的,并不是利用spring相关注解进行实例化,所以大家参考的时候要注意,如果在上面加上spring的@Service等注解,项目会无法启动,报错信息是发现多个handler实例

这里欢迎大家对我提出宝贵的建议,我自身对这个责任链模式的使用并不是很熟练,也没有在项目中实践过,如果大家有更好的案例欢迎评论出来,我会去学习的!

相关推荐
张宇Joaquin几秒前
鲲鹏统一并行加速库KUPL--众核并行能力介绍
java·开发语言·网络
宸津-代码粉碎机34 分钟前
AI攻防战升级!基于Spring AI构建Java应用自动免疫安全体系
java·大数据·开发语言·人工智能·python·安全·spring
2601_963749101 小时前
越华环保集团数字化污水治理:端边云采集架构与平台对接实现
java·大数据·架构
xcLeigh2 小时前
Go入门:整数类型的溢出与安全边界
java·安全·golang
源码宝2 小时前
SpringBoot+Vue2 诊所门诊管理系统,完整前后端源码,可直接部署上线
java·源码·his系统·门诊系统·程序代码·诊所系统·门诊his
yychen_java2 小时前
九:Text-to-SQL 智能数据查询与 Human-in-the-Loop 人机协作
java·人工智能·架构
user_admin_god3 小时前
数据采集/交换系统设计经验
spring boot·spring·策略模式
码匠许师傅3 小时前
【设计模式精讲】14.外观模式(Facade)
c++·设计模式·uml·外观模式
lhldsg4 小时前
智慧场馆解决方案小程序开发实战:从架构设计到部署指南
java·小程序·uni-app
Freak嵌入式4 小时前
Pico UART 数据收发实战:硬件配置、MicroPython 编程
java·开发语言·单片机·嵌入式硬件·生活