基于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实例

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

相关推荐
Q_Q5110082857 分钟前
python的婚纱影楼管理系统
开发语言·spring boot·python·django·flask·node.js·php
长风破浪会有时呀19 分钟前
记一次接口优化历程 CountDownLatch
java
极光雨雨26 分钟前
【设计模式】单例模式 饿汉式单例与懒汉式单例
单例模式·设计模式
云朵大王44 分钟前
SQL 视图与事务知识点详解及练习题
java·大数据·数据库
我爱Jack1 小时前
深入解析 LinkedList
java·开发语言
一线大码2 小时前
Gradle 高级篇之构建多模块项目的方法
spring boot·gradle·intellij idea
27669582922 小时前
tiktok 弹幕 逆向分析
java·python·tiktok·tiktok弹幕·tiktok弹幕逆向分析·a-bogus·x-gnarly
用户40315986396633 小时前
多窗口事件分发系统
java·算法
用户40315986396633 小时前
ARP 缓存与报文转发模拟
java·算法
小林ixn3 小时前
大一新手小白跟黑马学习的第一个图形化项目:拼图小游戏(java)
java