zoukankan      html  css  js  c++  java
  • 责任链模式

    责任链模式的定义与特点

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

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

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

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

     责任链模式的结构

    责任链模式的应用

    传统实现

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

    常见的写法如下:

    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 就是一个典型的责任链模式,它可以让一个请求在整个管道中进行流转。

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

     

  • 相关阅读:
    is_numeric — 检测变量是否为数字或数字字符串
    intval — 获取变量的整数值
    php获取数组最后一个值
    js正則匹配经纬度(经纬度逗号隔开)
    安装netcat(-bash: netcat: command not found)
    提示-bash: telnet: command not found的解决方法
    Laravel中使用Redis
    鏈接Redis報錯`AUTH` failed: ERR Client sent AUTH, but no password is set [tcp://127.0.0.1:6379]
    使用composer遇到的坑
    laravel的ORM模型的find(),findOrFail(),first(),firstOrFail(),get(),list(),toArray()之间的区别
  • 原文地址:https://www.cnblogs.com/Joy-Hu/p/10730692.html
Copyright © 2011-2022 走看看