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

news2024/9/24 17:16:29

前言

        前面荔枝梳理了有关单例模式、策略模式的相关知识,这篇文章荔枝将沿用之前的写法根据示例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.coloradmin.cn/o/985947.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【OJ比赛日历】快周末了,不来一场比赛吗? #09.09-09.15 #15场

CompHub[1] 实时聚合多平台的数据类(Kaggle、天池…)和OJ类(Leetcode、牛客…&#xff09;比赛。本账号会推送最新的比赛消息&#xff0c;欢迎关注&#xff01; 以下信息仅供参考&#xff0c;以比赛官网为准 目录 2023-09-09&#xff08;周六&#xff09; #5场比赛2023-09-10…

Kafka3.0.0版本——消费者(独立消费者消费某一个主题中某个分区数据案例__订阅分区)

目录 一、独立消费者消费某一个主题中某个分区数据案例1.1、案例需求1.2、案例代码1.3、测试 一、独立消费者消费某一个主题中某个分区数据案例 1.1、案例需求 创建一个独立消费者&#xff0c;消费firstTopic主题 0 号分区的数据&#xff0c;所下图所示&#xff1a; 1.2、案…

【逗老师的无线电】MMDVM盒子安装高颜值仪表盘

目录 开篇、高颜值仪表盘展示1、实时通联卡片2、精简信息仪表盘3、主仪表盘 一、下载W0CHP-PiStar-Dash二、安装1、解压2、刻录SD卡 三、基础配置1、首次启动2、初始化配置2.1、先配置联网2.2、配置热点参数2.3、配置DMR参数2.4、显示屏配置 3、通联测试 四、进阶操作1、自定义…

Unity——脚本与导航系统(上)

Unity内置了一个比较完善的导航系统&#xff0c;一般称为Nav Mesh&#xff08;导航网格&#xff09;&#xff0c;用它可以满足大多数游戏中角色自动导航的需求。 一、导航系统相关组件 Unity的导航系统由以下几个部分组成&#xff1a; Nav Mesh。Nav Mesh与具体的场景关联&…

Linux目录结构和远程使用

目录名作用根目录 ‘/’文件系统结构的起始点/root系统管理员的工作目录/home普通用户工作目录/bin存放二进制可执行文件&#xff0c;存放最经常使用的命令/sbin系统管理员使用的系统管理程序/boot启动linux时使用的一些核心文件/dev设备文件&#xff0c;包括块设备和字符设备/…

Google Chrome如何同步书签

前提 先确保能科学上网 操作步骤 然后&#xff0c;要在设备之间同步Google Chrome书签&#xff0c;可以用以下步骤&#xff1a; 在您的Mac和Windows设备上安装Google Chrome浏览器。 在您的Google Chrome账户中启用同步功能。如果您还没有Google Chrome账户&#xff0c;请先…

导入jdk源码并进行使用

jdk下载地址 JDK1.8源码下载地址 idea打开jdk项目 打开项目结构&#xff0c;进入SDK这一栏&#xff0c;选择一个使用的jdk&#xff0c;选择jdk的类路径 将类路径进行删除&#xff0c;并且添加我们自己下载的jdk中的src文件夹到类路径

去掉Egde浏览器选择文本弹出的搜索小按钮

去掉Egde浏览器选择文本弹出的搜索小按钮 小按钮 去掉&#xff1a;在设置中找到选择文本时的微型菜单&#xff0c;关闭【选择文本时显示迷你菜单】选项

洛谷 Array 数论

题目&#xff1a; 对于长度为n的数组A&#xff0c;A中只包含从1到n的整数&#xff08;可重复&#xff09;。如果A单调不上升或单调不下降&#xff0c;A就可称为美丽的。 找出在长度为n时&#xff0c;有几个美丽的A。 思路&#xff1a; 这是一道数论题。 我们先找找“单调不递…

计算机网络第三章——数据链路层(下)

提示&#xff1a;任何命运无论多么复杂&#xff0c;都只是反映在一瞬间 文章目录 局域网以太网无线局域网广域网及相关协议HDLC协议&#xff08;408已删&#xff09;链路层设备冲突域和广播域 局域网 局域网也有无线局域网&#xff0c; 我们日常生活中局域网主要是使用总线型这…

Linux 服务器运维管理面板1Panel体验

地址 https://github.com/1Panel-dev/1Panel 安装 根据GitHub提示运行即可 curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && sudo bash quick_start.sh安装成功&#xff0c;期间会安装docker 、docker-compose

box_iou交并比及assign_anchor_to_bbox个人理解

接上篇文章&#xff0c;李沐沐神的《动手学深度学习》中的show_bboxes还是比较好理解的&#xff0c;于是来看这两个方法 以下内容建议对照源代码理解 def box_iou 首先我们来设置boxes1和boxes2的初始值 boxes1 torch.tensor([[1,2,5,6],[2,1,4,6],[-1,2,7,6],[1,2,5,8]]) …

ubuntu14.04改静态ip

现在可能已经用ubuntu14.04的人已经不多了&#xff0c;这里讲一下Ubuntu14.04怎么改静态ip 第一步&#xff1a;输入ifconfig查看ip和子网掩码 第二步&#xff1a;输入route -n查看网关 上面ip是192.168.88.136&#xff0c;子网掩码是255.255.255.0&#xff0c;网关是192.168.…

中国ui设计师年终工作总结

一、萌芽阶段 记得初次应聘时&#xff0c;我对公司的认识仅仅局限于行业之一&#xff0c;对UI设计师一职的认识也局限于从事相对单纯的界面的设计创意和美术执行工作。除此之外&#xff0c;便一无所知了。所以&#xff0c;试用期中如何去认识、了解并熟悉自己所从事的行业&…

C++,day0907

#include <iostream>using namespace std; struct stu { private:int num; private:double score[32];public:void setNum(){cout <<"请输入学生人数:";cin >>num;}void input(){cout<<"请输入学生的成绩:"<<endl;for(int i…

Spring IOC之ListableBeanFactory

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

go work 不同包下mod + work实现.go文件的互相调用

一、文件架构 . ├── go.mod ├── go.work ├── main │ └── main.go └── util├── go.mod└── util.go其中go.mod module testgo 1.21.0其中go.work go 1.21.0use (../util )main/main.go 1 package main …

海外风控中这类征信数据与模型实践,实操落地效果最有效

今天的文章我们跟大家详细介绍&#xff0c;海外现金贷征信数据的特征介绍与建模实践。 希望今天的内容可以帮助各位童鞋了解海外现金贷的数据维度及其特征体系&#xff0c;并重点熟悉特征衍生的加工方法&#xff0c;在实际任务场景中加以实践应用。 首先&#xff0c;我们需要明…

从驾考科目二到自动驾驶,聊聊 GPU 为什么对自动驾驶很重要

“下一个项目&#xff0c;坡道起步。” …… “考试不合格&#xff0c;请将车子开到起点&#xff0c;重新验证考试。你的扣分项是&#xff1a;起步时间超30秒&#xff1a;扣100分。行驶过程中车轮轧到边线&#xff1a;扣100分。” 想必经历过驾驶证考试的同学&#xff0c;对…

Unity 之Material 类型和 MeshRenderer 组件中的 Materials 之间有一些重要的区别

文章目录 区别代码例子 区别 在Unity中&#xff0c;Material 类型和 MeshRenderer 组件中的 Materials 之间有一些重要的区别。 Material 类型&#xff1a; Material 是 Unity 中用来定义渲染属性的资源。它包含了一系列定义了如何绘制一个对象的属性&#xff0c;比如颜色、纹…