Skip to content

责任链模式

一、介绍

责任链设计模式(Chain of Responsibility Pattern),当客户端发出一个请求,链上的对象都有机会来处理这一请求,而客户端不需要知道谁是具体的处理对象,让多个对象都有机会处理请求,避免请求的发送者和接收者之间的耦合关系,将这个对象连成一条调用链,并沿着这条链传递该请求,直到有一个对象处理它才终止

有两个核心行为:一是处理请求,二是将请求传递到下一节点

二、应用场景

  • Apache Tomcat 对 Encoding 编码处理的处理,SpringBoot里面的拦截器、过滤器链
  • 在请求处理者不明确的情况下向多个对象中的一个提交请求
  • 如果有多个对象可以处理同一个请求,但是具体由哪个对象处理是由运行时刻动态决定的,这种对象就可以使用职责链模式

三、角色

  • Handler抽象处理者:定义了一个处理请求的接口
  • ConcreteHandler具体处理者: 处理所负责的请求,可访问它的后续节点,如果可处理该请求就处理,否则就将该请求转发给它的后续节点

四、优缺点

  • 优点

    • 客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者 降低了耦合度
    • 通过改变链内的调动它们的次序,允许动态地新增或者删除处理类,比较很方便维护
    • 增强了系统的可扩展性,可以根据需要增加新的请求处理类,满足开闭原则
    • 每个类只需要处理自己该处理的工作,明确各类的责任范围,满足单一职责原则
  • 缺点

    • 处理都分散到了单独的职责对象中,每个对象功能单一,要把整个流程处理完,需要很多的职责对象,会产生大量的细粒度职责对象
    • 不能保证请求一定被接收;
    • 如果链路比较长,系统性能将受到一定影响,而且在进行代码调试时不太方便

五、代码

参数对象

package com.lcy.study.design.chain;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * @Description 过滤器对象
 * @Author lcy
 * @Date 2021/7/27 15:03
 */
@Data
@AllArgsConstructor
public class FilterEntity {

    /**
     * token
     */
    private String token;

}

责任链抽象类

package com.lcy.study.design.chain;

import lombok.Setter;

/**
 * @Description 过滤器责任链抽象类
 * @Author lcy
 * @Date 2021/7/27 15:02
 */
public abstract class FilterChain {

    /**
     * 过滤器名称
     */
    protected String name;

    /**
     * 下一个过滤器
     */
    @Setter
    protected FilterChain nextFilterChain;

    public FilterChain(String name){
        this.name = name;
    }

    /**
     * 过滤方法
     * @param filterEntity 参数
     * @author lcy
     * @date 2021/7/27 15:07
     **/
    public abstract void doChain(FilterEntity filterEntity);

    /**
     * 执行下一个过滤器
     * @param filterEntity 参数
     * @author lcy
     * @date 2021/7/27 15:08
     **/
    protected void doNext(FilterEntity filterEntity){
        if (nextFilterChain == null) {
            System.out.println("过滤器执行完毕");
        } else {
            nextFilterChain.doChain(filterEntity);
        }
    }

}

具体责任类--过滤器

package com.lcy.study.design.chain;

/**
 * @Description 过滤器责任链抽象类
 * @Author lcy
 * @Date 2021/7/27 15:02
 */
public class FirstFilterChain extends FilterChain {

    public FirstFilterChain(String name){
        super(name);
    }

    @Override public void doChain(FilterEntity filterEntity){
        System.out.println(name + "过滤器");
        if (filterEntity.getToken() == null || "".equals(filterEntity.getToken())) {
            System.out.println("验证完毕");
        } else {
            doNext(filterEntity);
        }
    }
}
package com.lcy.study.design.chain;

/**
 * @Description 过滤器责任链抽象类
 * @Author lcy
 * @Date 2021/7/27 15:02
 */
public class SecondFilterChain extends FilterChain {

    public SecondFilterChain(String name){
        super(name);
    }

    @Override public void doChain(FilterEntity filterEntity){
        System.out.println(name + "过滤器");
        if ("user".equals(filterEntity.getToken())) {
            System.out.println("验证完毕");
        } else {
            doNext(filterEntity);
        }
    }
}

调用类

package com.lcy.study.design.chain;

/**
 * @Description 责任链设计模式调用类
 * @Author lcy
 * @Date 2021/7/27 15:13
 */
public class ChainMain {

    public static void main(String[] args){

        FilterChain firstFilterChain = new FirstFilterChain("first");
        FilterChain secondFilterChain = new SecondFilterChain("second");

        firstFilterChain.setNextFilterChain(secondFilterChain);
        firstFilterChain.doChain(new FilterEntity("user"));
        firstFilterChain.doChain(new FilterEntity(""));

    }

}