设计模式之责任链模式

1. 责任链模式

1.1 责任链模式定义

当你想要让一个以上的对象 有机会能够处理某个请求的时候,就使用责任链模式

责任链模式为请求创建了一个接收者对象的链。执行链上有多个对象节点,每个对象节点都有机会(条件匹配)处理请求事务,如果某个对象节点处理完了,就可以根据实际业务需求传递给下一个节点继续处理或者返回处理完毕。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。

关键点

  • 解耦:请求的发送者不需要知道谁会处理这个请求,也不需要知道处理请求的具体过程。
  • 灵活性:可以在运行时动态地改变处理者链,使得系统更加灵活。
  • 可扩展性:可以轻松地向现有系统中添加新的处理者,而无需修改现有的代码。

结构

  • 抽象处理者(Handler) :定义了一个处理请求的接口,并且有一个指向其后续处理者的引用。

    具体处理者(Concrete Handler):实现抽象处理者的接口,根据实际情况决定是否处理请求或将其转发给下一个处理者。

  • 具体处理者(Concrete Handler):实现抽象处理者的接口,根据实际情况决定是否处理请求或将其转发给下一个处理者。

  • 客户端(Client):创建一个处理者链,并将请求提交给第一个处理者。

Spring AOP、Spring事务管理的一个重要特性是它使用了责任链模式;Spring MVC中的拦截器(Interceptor)等都用到了责任链模式。

1.2 责任链模式使用

责任链模式怎么使用呢?

  • 一个接口或者抽象类
  • 每个对象差异化处理
  • 对象链(数组)初始化(连起来)

1.3 具体代码

首先创建一个接口或者抽象类
java 复制代码
public abstract class AbstractHandler {

    /**
     * 责任链中的下一个对象
     */
    private AbstractHandler nextHandler;

    /**
     * 责任链的下一个对象
     */
    public void setNextHandler(AbstractHandler nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * 具体参数拦截逻辑,给子类去实现
     */
    public void filter(HttpServletRequest request, HttpServletResponse response) {
        doFilter(request, response);
        if (getNextHandler() != null) {
            getNextHandler().filter(request, response);
        }
    }

    public AbstractHandler getNextHandler() {
        return nextHandler;
    }

    /**
     * 抽象方法
     * @param filterRequest
     * @param response
     */
    abstract void doFilter(HttpServletRequest filterRequest, HttpServletResponse response);

}
每个对象差异化处理
java 复制代码
@Component
@Order(1)
public class CheckRequestHeaderFilterObject extends AbstractHandler {
    @Override
    void doFilter(HttpServletRequest filterRequest, HttpServletResponse response) {
        System.out.println("请求头校验");
    }
}
java 复制代码
@Component
@Order(2)
public class CheckCorsFilterObject extends AbstractHandler{
    @Override
    void doFilter(HttpServletRequest filterRequest, HttpServletResponse response) {
        System.out.println("cors校验");
    }
}
java 复制代码
@Component
@Order(3)
public class CheckParamFilterObject extends AbstractHandler{
    @Override
    void doFilter(HttpServletRequest filterRequest, HttpServletResponse response) {
        System.out.println("参数合法校验");
    }
}
java 复制代码
@Component
@Order(4)
public class CheckBlackFilterObject extends AbstractHandler{
    @Override
    void doFilter(HttpServletRequest filterRequest, HttpServletResponse response) {
        System.out.println("黑名单校验");
    }
}
对象链连起来(初始化)&& 使用
java 复制代码
@Component("ChainPatternTest")
public class ChainPatternTest {

    /**
     * 自动注入各个责任链的对象
     */
    @Resource
    private List<AbstractHandler> abstractHandleList;

    private AbstractHandler abstractHandler;

    /**
     * spring注入后自动执行,责任链的对象连接起来
     */
    @PostConstruct
    public void initializeChainFilter() {
        for (int i = 0; i < abstractHandleList.size(); i++) {
            if (i == 0) {
                abstractHandler = abstractHandleList.get(0);
            } else {
                AbstractHandler currentHandler = abstractHandleList.get(i - 1);
                AbstractHandler nextHandler = abstractHandleList.get(i);
                currentHandler.setNextHandler(nextHandler);
            }
        }
    }

    /**
     * 直接调用这个方法使用,根据实际使用来返回数据内容等
     *
     * @param request
     * @param response
     * @return
     */
    public HttpServletResponse exec(HttpServletRequest request, HttpServletResponse response) {
        abstractHandler.filter(request, response);
        return response;
    }

    public AbstractHandler getAbstractHandler() {
        return abstractHandler;
    }

    public void setAbstractHandler(AbstractHandler abstractHandler) {
        this.abstractHandler = abstractHandler;
    }
}

调用运行结果如下:

json 复制代码
请求头校验
cors校验
参数合法校验
黑名单校验
相关推荐
咸鱼2.01 小时前
【java入门到放弃】Dubbo
java·开发语言·dubbo
JAVA面经实录9177 小时前
Java企业级工程化·终极完整版背诵手册(无遗漏、全覆盖、面试+落地通用)
java·开发语言·面试
许彰午9 小时前
CacheSQL(二):主从复制——OpLog 环形缓冲区与故障自动恢复
java·数据库·缓存
Bat U10 小时前
JavaEE|多线程初阶(七)
java·开发语言
掌心向暖RPA自动化12 小时前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa
日取其半万世不竭13 小时前
Minecraft Java版社区服务器搭建教程(Linux,适合新手)
java·linux·服务器
TeamDev13 小时前
JxBrowser 9.0.0 版本发布啦!
java·前端·混合应用·jxbrowser·浏览器控件·跨平台渲染·原声输入
AI人工智能+电脑小能手14 小时前
【大白话说Java面试题】【Java基础篇】第24题:Java面向对象有哪些特征
java·开发语言·后端·面试
geovindu14 小时前
go: Strategy Pattern
开发语言·设计模式·golang·策略模式
AI人工智能+电脑小能手14 小时前
【大白话说Java面试题】【Java基础篇】第25题:JDK1.8的新特性有哪些
java·开发语言·后端·面试