责任链模式

责任链模式的定义与特点

责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系,将这个对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理他为止

标准的责任链模式,个人总结下来有如下几个特点:

  • 链上的每个对象都有机会处理请求
  • 链上的每个对象都持有下一个要处理对象的引用
  • 链上的某个对象无法处理当前请求,那么它会把相同的请求传给下一个对象

纯责任链模式和不纯的责任链模式
如果一个类要么承担责任处理请求要么将请求踢给下一个处理类,则被称为纯责任链模式。
如果一个类承担了一部分责任,还将请求踢给下一个处理类,则被称为不纯的责任链模式。

 责任链模式的结构

责任链模式的应用

传统实现

假设这样的场景:传入了一段内容,需要对这段文本进行加工;比如过滤敏感词、错别字修改、最后署上版权等操作。

常见的写法如下:

public class Main {
    public static void main(String[] args) {
        String msg = "内容内容内容" ;

        String result = Process.sensitiveWord()
                .typo()
                .copyright();
    }
}

这样看似没啥问题也能解决需求,但如果我还需要为为内容加上一个统一的标题呢?在现有的方式下就不得不新增处理方法,并且是在这个客户端(Process)的基础上进行新增。

显然这样的扩展性不好。

责任链模式实现

该需求非常的符合对某一个对象、请求进行一系列处理的特征。于是我们将代码修改:

这时 Process 就是一个接口了,用于定义真正的处理函数。

public interface Process {

    /**
     * 执行处理
     * @param msg
     */
    void doProcess(String msg) ;
}

同时之前对内容的各种处理只需要实现该接口即可:

public class SensitiveWordProcess implements Process {
    @Override
    public void doProcess(String msg) {
        System.out.println(msg + "敏感词处理");
    }
}

public class CopyrightProcess implements Process {

    @Override
    public void doProcess(String msg) {
        System.out.println(msg + "版权处理");
    }
}

public class CopyrightProcess implements Process {

    @Override
    public void doProcess(String msg) {
        System.out.println(msg + "版权处理");
    }
}

然后只需要给客户端提供一个执行入口以及添加责任链的入口即可:

public class MsgProcessChain {

    private List<Process> chains = new ArrayList<>() ;

    /**
     * 添加责任链
     * @param process
     * @return
     */
    public MsgProcessChain addChain(Process process){
        chains.add(process) ;
        return this ;
    }

    /**
     * 执行处理
     * @param msg
     */
    public void process(String msg){
        for (Process chain : chains) {
            chain.doProcess(msg);
        }
    }
}

这样使用起来就非常简单:

public class Main {
    public static void main(String[] args) {
        String msg = "内容内容内容==" ;

        MsgProcessChain chain = new MsgProcessChain()
                .addChain(new SensitiveWordProcess())
                .addChain(new TypoProcess())
                .addChain(new CopyrightProcess()) ;

        chain.process(msg) ;
    }
}

当我需要再增加一个处理逻辑时只需要添加一个处理单元即可(addChain(Process process)),并对客户端 chain.process(msg) 是无感知的,不需要做任何的改动。

责任链模式的使用场景

1、典型的就是Servlet中的Filter,有了上面的分析,大家应该也可以理解Servlet中责任链模式的工作原理了,然后为什么一个一个的Filter需要配置在web.xml中

2、Netty 中的 pipeline 就是一个典型的责任链模式,它可以让一个请求在整个管道中进行流转。

通过官方图就可以非常清楚的看出是一个责任链模式:

 

原文地址:https://www.cnblogs.com/Joy-Hu/p/10730692.html