软件体系结构--责任链模式

news/2024/5/19 15:36:33 标签: 软件体系结构, 设计模式, 责任链模式

文章目录

  • 概念
  • 例子
  • 总结
    • 优点
    • 缺点

概念

责任链模式为某个请求创建一个对象链,每个对象依次检查此请求,并对其进行处理,或者将它传给链中的下一个对象。

链表是很常见一种数据结构,责任链模式的结构其实和链表相差无几,唯一的区别就是责任链模式中所有的对象都有一个共同的父类(或接口):

image

责任链模式中,N个 Handler 子类都处理同一个请求,只不过具体的职责有所差别。

当有一个请求进入时,先经过 AHandler 的 handlerRequest 方法,然后再把请求传递给 BHandler,B 处理完再把请求传递给 CHandler,以此类推,形成一个链条。链条上的每一个对象所承担的责任各不相同,这就是责任链模式

例子

现在我们模拟一个场景:论坛用户发表帖子,但是常常会有用户一些不良的信息,如广告信息,涉黄信息,涉及政治的敏感词等。这时我们就可以使用责任链模式来过滤用户发表的信息。

先定义所有责任链对象的父类:

/**
 * 帖子处理器
 */
public abstract class PostHandler {

    /**
     * 后继者
     */
    protected PostHandler successor;

    public void setSuccessor(PostHandler handler){
        this.successor = handler;
    }

    public abstract void handlerRequest(Post post);

    protected final void next(Post post){
        if(this.successor != null){
            this.successor.handlerRequest(post);
        }
    }
}

父类 Handler 主要封装了传递请求等方法,其中要注意的有两点:

  • successor,后继者,这个属性很重要,它保存了责任链中下一个处理器
  • 在 next() 方法中(方法名自己随便取),当请求传递到最后一个责任对象时,已经没有后继者继续处理请求了,因此要对 successor 做判空处理,避免抛出空指针异常。
  • 处理请求的handlerRequest 的入参和返回类型可以根据实际情况修改,可以在该方法中抛出异常来中断请求

广告处理器:

/**
 * 广告处理器
 */
public class AdHandler extends PostHandler {

    @Override
    public void handlerRequest(Post post) {
        //屏蔽广告内容
        String content = post.getContent();
        //.....
        content = content.replace("广告","**");
        post.setContent(content);

        System.out.println("过滤广告...");
        //传递给下一个处理器
        next(post);
    }
}

涉黄处理器:

/**
 * 涉黄处理器
 */
public class YellowHandler extends PostHandler {

    @Override
    public void handlerRequest(Post post) {
        //屏蔽涉黄内容
        String content = post.getContent();
        //.....
        content = content.replace("涉黄","**");
        post.setContent(content);

        System.out.println("过滤涉黄内容...");
        //传递给下一个处理器
        next(post);
    }
}

调用:

//创建责任对象
PostHandler adHandler = new AdHandler();
PostHandler yellowHandler = new YellowHandler();
PostHandler swHandler = new SensitiveWordsHandler();

//形成责任链
yellowHandler.setSuccessor(swHandler);
adHandler.setSuccessor(yellowHandler);

Post post = new Post();
post.setContent("我是正常内容,我是广告,我是涉黄,我是敏感词,我是正常内容");

System.out.println("过滤前的内容为:"+post.getContent());

post = adHandler.handlerRequest(post);

System.out.println("过滤后的内容为:"+post.getContent());

总结

可能大家有疑问,为什么不把所有的过滤器写在一个方法里呢?因为这样做又破坏了开放封闭原则。我们需要使用责任链模式,能够在不修改已有代码的情况下扩展新功能。

责任链模式将常用于过滤器,拦截器,事件(鼠标键盘事件,冒泡事件等)等场景

优点

  • 请求者和接收者解耦
    可以动态的增加或减少责任链上的对象,或者修改顺序

缺点

  • 调用者不知道请求可能被哪些责任链对象处理,不利于排错
    用户请求可能被责任链中途拦截,最终未必被真正执行,这点既是优点也是缺点,我们可以利用它做权限控制拦截器

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

相关文章

python修改环境变量_python 读取修改环境变量

使用os.environ来读取和修改环境变量:import osprint (os.environ["TEMP"])mydir "c:\\mydir"os.environ["MYDIR"] mydirprint (os.environ["MYDIR"])pathV os.environ["PATH"]print (pathV)os.environ["…

python中的正则表达式re_python中的正则表达式(re模块)

一、简介正则表达式本身是一种小型的、高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。二、正则表达式中常用的…

语法制导翻译方案SDT

文章目录概念将S-SDD转换为SDTS-SDD的SDT实现将L-SDD转换为SDTL-SDD的SDT实现概念 语法制导翻译方案SDT是在产生式右部嵌入了程序片段(称为语义动作)的CFG 例如: SDT可以看做是SDD的具体实施方案。 在两种情况下,SDT可以在语…

类型表达式

文章目录类型表达式基本类型类型构造符数组构造符指针构造符笛卡尔乘积构造符$✖$函数构造符$\rightarrow$记录构造符类型表达式 基本类型 基本类型是类型表达式 integerrealcharbooleantype_error(出错类型)void(无类型) 可以为类型表达式命名,类型名也是类型表…

onctlcolor改变checkbox文字颜色_你见过这么有趣的文字云排版吗?

今天介绍​一个有趣的文字排版方式:文字云(也可以叫做词云)我们先来看看文字云长什么样子~文字云主要用于盘点的展示,造型新颖独特,我们在公众号配图的时候也可以考虑这种形式。接下来我就给大家分享两款制作文字云的软…

python依赖注入_python 抽象类、抽象方法、接口、依赖注入、SOLIP

1、程序设计原则:SOLIPSOLIP设计原则1、单一责任原则(SRP)一个对象对只应该为一个元素负责2、开放封闭原则(OCP)对扩展开放,修改封闭3、里氏替换原则(LSP)可以使用任何派生类替换基类4、接口分离原则(ISP)对于接口进行分类避免一个接口的方法过多5、依赖…

Linux—用make进行宏编译

文章目录gcc的简易用法为什么要用makemakefile的基本语法与变量gcc的简易用法 gcc - c hello.c:会自动生成hello.o这个文件,但并不会生成可执行文件gcc -O helo.c -c:会自动的生成hello.o这个文件,并进行优化gcc -o hello hello.…

将中文数字转为数字

1 /**2 * 根据输入的中文转为数字3 * param String chineseNumber4 * return int5 */6 public static int chineseNumber2Int(String chineseNumber){7 String statechineseNumber;8 int result0;9 10 i…