软件设计模式(三):责任链模式

news/2024/5/19 14:04:20 标签: 设计模式, 责任链模式

前言

        前面荔枝梳理了有关单例模式、策略模式的相关知识,这篇文章荔枝将沿用之前的写法根据示例demo来体会这种责任链设计模式,希望对有需要的小伙伴有帮助吧哈哈哈哈哈哈~~~


文章目录

前言

责任链模式 

1 简单场景 

2 责任链模式理解 

 3 Java下servlet包中的doFilter

总结


责任链模式 

        责任链模式是将一系列处理单元通过指针连接起来,按顺序执行下去,完成对请求的处理,当责任链模式中一个处理单元不适合处理该请求时,将继续传递该请求到下一单元,其往往使用一个共享的上下文对象来包装请求,该上下文对象同样包含责任链的输出模型。责任链顺序执行的过程,是上下文输出模型逐渐完善的过程。

1 简单场景 

为了更好地理解,我们首先需要设计场景来理解:现在需要开发一个过滤机制来Msg对象中的非法输入,下面的代码是未使用责任链的模式。 

package com.crj.test;

import java.util.ArrayList;
import java.util.List;

public class SimpleMain {
    public static void main(String[] args) {
        Msg msg = new Msg();
        msg.setMsg("伪装一下注入:<script>关键词。。999......");

        List<Filter> filters = new ArrayList<>();
        filters.add(new HTMLFilter());
        filters.add(new SensitiveFilter());

        for(Filter f:filters){
            f.doFilter(msg);
        }

        System.out.println(msg);
    }
}

class Msg{
    String name;
    String msg;

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    @Override
    public String toString() {
        return "Msg{" +
                "name='" + name + '\'' +
                ", msg='" + msg + '\'' +
                '}';
    }

}

interface Filter{
    void doFilter(Msg m);
}

/**
 * HTML过滤
 */
class HTMLFilter implements Filter{
    @Override
    public void doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace('<','[');
        r = r.replace('>',']');
        m.setMsg(r);
    }
}
/**
 * 敏感词过滤
 */
class  SensitiveFilter implements Filter{
    @Override
    public void doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace("999","666");
        m.setMsg(r);
    }
}

2 责任链模式理解 

        使用责任链模式来编写demo,可以看到我们添加了一个类FilterChain,通过该类中封装的add()方法来将不同的过滤规则进行添加,同时调用不同的规则对象各自声明的重写的doFilter方法实现过滤。这个过程就像是一串糖葫芦,一颗一颗需要用一根竹签串起来,这个竹签就是FilterChain类,糖葫芦就是不同的过滤规则类。

package com.crj.test;

import java.util.ArrayList;
import java.util.List;

public class SimpleMain {
    public static void main(String[] args) {
        Msg msg = new Msg();
        msg.setMsg("伪装一下注入:<script>关键词。。999......");

        FilterChain fc = new FilterChain();
        fc.add(new HTMLFilter());
        fc.add(new SensitiveFilter());

        fc.doFilter(msg);

        System.out.println(msg);
    }
}

class Msg{
    String name;
    String msg;

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public String getMsg() {
        return msg;
    }

    @Override
    public String toString() {
        return "Msg{" +
                "name='" + name + '\'' +
                ", msg='" + msg + '\'' +
                '}';
    }

}

interface Filter{
    void doFilter(Msg m);
}

/**
 * HTML过滤
 */
class HTMLFilter implements Filter{
    @Override
    public void doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace('<','[');
        r = r.replace('>',']');
        m.setMsg(r);
    }
}
/**
 * 敏感词过滤
 */
class  SensitiveFilter implements Filter{
    @Override
    public void doFilter(Msg m) {
        String r = m.getMsg();
        r = r.replace("999","666");
        m.setMsg(r);
    }
}
/**
 * 过滤链
 */
class FilterChain{
    List<Filter> filters = new ArrayList<>();
    public void add(Filter filter){
        filters.add(filter);
    }
    public void doFilter(Msg m){
        for(Filter f:filters){
            f.doFilter(m);
        }
    }
}

 3 Java下servlet包中的doFilter

        Java EEJDK中提供了一个在servlet包下的doFilter方法实现了责任链模式,具体的参数主要有三个:request、response和FilterChain类型的chain。该方法可以实现对于请求和响应同时进行过滤,即假设有一个请求打过来,三个过滤规则A、B、C按照A-B-C的顺序过滤,当请求响应后 发出的Response会按照C-B-A的规则过滤。这个过程的实现类似于递归算法。 

        我们可以通过这个图来理解这个方法中责任链调用的递归过程,每一次请求打在过滤类上进行处理完成后,就会调用doFilter()方法,并将指针指向下一个过滤类处理请求,下一个类处理后执行doFilter()方法查看是否index==责任链列表的长度,是的话就会返回并回退到上一个过滤类中的doFilter()方法执行并返回。 

按照需求我们需要自行封装Request和Response类、定义Filter类及其相应的实现类,封装的FilterChain类实现具体的责任链模式,demo如下:

package com.crj.test2;

import java.util.ArrayList;
import java.util.List;

public class ServletChain {
    public static void main(String[] args) {
        Request request = new Request();
        request.str = "大家好999<script>";
        Response response = new Response();
        response.str = "response";

        FilterChain chain = new FilterChain();
        chain.add(new HTMLFilter()).add(new SensitiveFilter());
        chain.doFilter(request,response,chain);
    }
}

/**
 * 处理对象类
 */
class Request{
    String str;
}
class Response{
    String str;
}

/**
 * Filter接口
 */
interface Filter{
    boolean doFilter(Request request,Response response,FilterChain chain);
}

/**
 * 两个过滤类
 */
class HTMLFilter implements Filter{
    @Override
    public boolean doFilter(Request request, Response response,FilterChain chain) {
        request.str = request.str.replaceAll("<", "[").replaceAll(">", "]") + "HTMLFilter()";
        chain.doFilter(request, response, chain);
        response.str += "--HTMLFilter()";
        return true;
    }
}

class SensitiveFilter implements Filter{
    @Override
    public boolean doFilter(Request request, Response response,FilterChain chain) {
        request.str = request.str.replaceAll("996", "955") + " SensitiveFilter()";
        chain.doFilter(request, response, chain);
        response.str += "--SensitiveFilter()";
        return true;
    }
}

/**
 * 责任链实现类
 */
class FilterChain implements Filter{
    List<Filter> filters = new ArrayList<>();

    int index = 0;
    public FilterChain add(Filter f){
        filters.add(f);
        return this;
    }

    @Override
    public boolean doFilter(Request request, Response response,FilterChain chain) {
        if(index==filters.size()) return false;
        Filter f = filters.get(index);
        index++;
        return f.doFilter(request,response,chain);
    }
}

文章主要使用的是马老师的课程中提供的案例,链接:

https://www.bilibili.com/video/BV1G44y1R7nv?p=14&vd_source=91c021af5a207c9fdf0bd7969d48cbf2


总结

        这篇文章中荔枝主要梳理了设计模式中的责任链模式的相关概念,在这里荔枝没有给出过多的概念性的东西而是侧重于代码场景来理解哈哈。设计模式荔枝学的好慢,最近课也多嘿,可能文章顺序发出来的有点乱。接下来荔枝也会持续学习并产出~~~一起加油转码ing~

今朝已然成为过去,明日依然向往未来!我是小荔枝,在技术成长的路上与你相伴,码文不易,麻烦举起小爪爪点个赞吧哈哈哈~~~ 比心心♥~~~


http://www.niftyadmin.cn/n/5008839.html

相关文章

2023年中国信通院铸基计划“文本图像篡改检测系统技术规范”研讨会成功召开

2023年中国信通院铸基计划“文本图像篡改检测系统技术规范”&#xff08;简称“规范”&#xff09;研讨会于2023年8月16日在中国信息通信研究院成功召开&#xff0c;来自中国信息通信研究院、上海合合信息科技股份有限公司&#xff08;简称“合合信息”&#xff09;、华南理工大…

【工作技术栈】【源码解读】一次springboot注入bean失败问题的排查过程

目录 前言现象分析原因解决方法思考感悟 前言 对这次的过程排查如果要形容的话&#xff0c;我觉得更像是悬疑剧&#xff0c;bean not found 这种错误&#xff0c;已经看腻了&#xff0c;甚至有时候都看不起这种错误&#xff0c;但是似乎这个想法被springboot听见了&#xff0c…

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码

【2023高教社杯】D题 圈养湖羊的空间利用率 问题分析、数学模型及MATLAB代码 1 题目 题目 D 题 圈养湖羊的空间利用率 规模化的圈养养殖场通常根据牲畜的性别和生长阶段分群饲养&#xff0c;适应不同种类、不同阶段的牲畜对空间的不同要求&#xff0c;以保障牲畜安全和健康&a…

正版软件 | CloudDrive 多云盘本地挂载管理工具

前言&#xff1a; CloudDrive 是一个强大的多云盘管理工具&#xff0c;提供一站式的多云盘解决方案&#xff0c;包括云盘本地挂载。旨在无缝集成多个云存储服务&#xff0c;统一整合到一个界面。轻松管理和访问所有云存储服务&#xff0c;无需在不同的应用程序和界面之间切换。…

deepstream6.2部署yolov5详细教程与代码解读

文章目录 引言一.环境安装1、yolov5环境安装2、deepstream环境安装 二、源码文件说明三.wts与cfg生成1、获得wts与cfg2、修改wts 四.libnvdsinfer_custom_impl_Yolo.so库生成五.修改配置文件六.运行demo 引言 DeepStream 是使用开源 GStreamer 框架构建的优化图形架构&#xf…

单例和静态类

C#中的单例&#xff08;Singleton&#xff09;和静态类&#xff08;Static Class&#xff09;是两种不同的设计模式&#xff0c;它们各自有不同的用途和特点。 单例模式是一种设计模式&#xff0c;它确保一个类只有一个实例&#xff0c;并提供全局访问点。通常&#xff0c;单例…

Nodejs+vue+mysql网上药店购药系统 9h2k5

本毕业设计的内容是设计并且实现一个基于vue.js框架的空巢老人购药系统。采用MYSQL为数据库开发平台&#xff0c;nodejs语言&#xff0c;网络信息服务作为应用服务器。空巢老人购药系统的功能已基本实现&#xff0c;主要用户、家属、养生知识、药品信息、身体信息等。 论文主要…

第六章 图 三、图的存储结构(邻接表、十字链表、邻接多重表)

一、邻接表法 &#xff08;1&#xff09;无向图 1.定义 与树的孩子表示法相似&#xff0c;以顺序表的数据域为头结点&#xff0c;往后存储一个单向链表&#xff0c;链表内的值表示与此结点相邻的结点。 2.度的计算 只需遍历某一结点的后接链表&#xff0c;就可以算出该节点…