职责链模式-请求的链式处理

news2024/11/13 8:04:12

 在实际开发中,对于一个请求我们要经过层层过滤:身份验证 -> 权限验证 -> 实际业务处理。请求沿着一个链在传递,每一层都可以处理该请求。而“职责链模式”就是专门用于处理这种请求链式传递的模式。

1 职责链模式概述

避免将请求发送者与请求接收者耦合在一起,让多个对象都有机会接收请求,将这些对象连接成一条链,并且沿着这条链传递请求,直到有对象处理它为止。

图 职责链结构

  1. Handler,抽象处理者,定义了一个处理请求的接口及一个抽象处理者类型的下家引用,一般设计为抽象类。处理者可以连城一条链条。
  2. ConcreteHandler,具体处理者,是抽象处理者的子类,可以处理用户请求。在处理请求之前需要进行判断,看着是否有相应的处理权限,如果可以处理就处理它,否则将请求转发给后继者。在具体处理者中可以访问链中下一对象,以便请求的转发。
public class Request {

    private String username;

    private String role;

    private String info;

    public Request(String username, String role, String info) {
        this.username = username;
        this.role = role;
        this.info = info;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getRole() {
        return role;
    }

    public void setRole(String role) {
        this.role = role;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}
public abstract class Handler {

    protected Handler handler;

    public void setHandler(Handler handler) {
        this.handler = handler;
    }

    public abstract void handler(Request request);

}

public class UsernameHandler extends Handler{

    @Override
    public void handler(Request request) {
        if ("admin".equals(request.getUsername())) {
            System.out.println("用户名错误--终止请求");
        } else {
            handler.handler(request);
        }
    }

}

public class RoleHandler extends Handler{
    @Override
    public void handler(Request request) {
        if (!"all".equals(request.getRole())) {
            System.out.println("没有相应权限--终止请求");
        } else {
            handler.handler(request);
        }
    }
}

public class ServiceHandler extends Handler{

    @Override
    public void handler(Request request) {
        System.out.println("具体业务处理:" + request.getInfo());
        System.out.println("请求处理完成");
    }

}
public class Client {

    private static Handler handler;

    static {
        Handler handler1 = new UsernameHandler();
        Handler handler2 = new RoleHandler();
        Handler handler3 = new ServiceHandler();

        handler1.setHandler(handler2);
        handler2.setHandler(handler3);
        handler = handler1;
    }

    public static void main(String[] args) {
        handler.handler(new Request("huang","sell","生成订单"));
        System.out.println("---------------");
        handler.handler(new Request("admin","all","提现"));
        System.out.println("---------------");
        handler.handler(new Request("customer","all","查询商品"));
//        运行结果:
//        没有相应权限--终止请求
//        ---------------
//        用户名错误--终止请求
//        ---------------
//        具体业务处理:查询商品
//        请求处理完成
    }

}

职责链模式本身不创建职责链,职责链由客户端创建。

1.1 纯的职责链模式

要求一个具体处理者对象要么承担全部责任,要么将责任推给下家。不允许出现某个具体处理者对象在承担了一部分或者全部责任后又将责任向下传递的情况。

而且,要求一个请求必须被某个处理者所接收,不能出现某个请求未被任何一个处理者对象处理的情况。

1.2 不纯的职责链模式

允许某个请求被一个具体处理者部分处理后再向下传递,或者一个具体处理者处理完某个请求后,后继处理者可以继续处理该请求,而且一个请求可以最终不被任何处理者对象所接收。

2 优缺点

优点:

  1. 使得一个对象无须知道是其他哪一个对象处理了其请求。对象仅需要知道该请求会被处理即可。接收者和发送者都没有对方明确的信息,且链中对象不需要知道链的结构,由客户端负责链的创建,降低了系统耦合度。
  2. 请求处理对象仅需维持一个指向后继者的引用,不需要维持它对所有的候选处理者的引用,可简化对象的相互连接。
  3. 给对象分派职责时,职责链可以提供更多的灵活性,可以通过在运行时对链进行动态的增加或修改来增加或改变处理一个请求的职责。
  4. 在系统中增加一个新的具体请求处理者时无须修改原有系统的代码,只需在客户端重新建链即可。符合开闭原则。

缺点:

  1. 由于一个请求没有明确的接收者,那不能保证它一定会被处理。
  2. 对于比较长的职责链,请求的处理可能涉及多个处理对象,系统性能受到一定影响,而且在进行代码调试时不太方便。
  3. 如果建链不当,可能会照成循环调用,将导致系统陷入死循环。

3 适用场景

  1. 有多个对象处理同一个请求,具体哪个对象处理该请求待运行时刻再确定。
  2. 在不明确指定接收者的情况下,向多个对象中的一个提交请求。
  3. 需要动态指定一组对象处理请求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/816062.html

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

相关文章

Kubernetes系列

文章目录 1 详解docker,踏入容器大门1.1 引言1.2 初始docker1.3 docker安装1.4 docker 卸载1.5 docker 核心概念和底层原理1.5.1 核心概念1.5.2 docker底层原理 1.6 细说docker镜像1.6.1 镜像的常用命令 1.7 docker 容器1.8 docker 容器数据卷1.8.1 直接命令添加1.8.2 Dockerfi…

2023-07-31 C语言根据错误号打印详细的错误信息perror(““) 或者strerror(errno)

一、C 语言可以使用perror("perror output"); 或 strerror(errno)打印详细的错误信息。 二、需要的头文件#include <errno.h>。 三、实例测试&#xff0c;这里我让open一个linux 底层杂项设备失败的情况&#xff0c;返回的是一个负数&#xff0c;强制返回-EN…

【shell】获取ping的时延数据并分析网络情况

网络情况经常让我们头疼&#xff0c;每次都需要手动在终端ping太麻烦了&#xff0c;不如写个脚本ping并将数据带上时间戳存入文件&#xff0c;然后也可以分析哪个时间段网络比较差。 创建一个demo.sh文件&#xff1a; #!/bin/bash # 清理日志 net_path"./network/"…

性能测试必备监控技能windows篇

前言 在手头没有专门的第三方监控时&#xff0c;该怎么监控服务指标呢&#xff1f;本篇就windows下监控进行分享&#xff0c;也是我们在进行性能测试时&#xff0c;必须掌握的。下面我们就windows下常用的三种监视工具进行说明&#xff1a; 任务管理器 资源监视器 性能监视器…

AD21 PCB设计的高级应用(一)BGA的扇出方式

&#xff08;一&#xff09;BGA的扇出方式 1.软件自动扇出方式2.手工扇出方式3.多种规格BGA的出现方式 1.软件自动扇出方式 在进行PCB设计时,常会遇到 BGA类型的封装&#xff0c;此类封装需要扇出用于后期的布线。BGA 扇出与否的比对如图所示。 (1)在进行利用软件自动扇出 BGA…

移动端适配布局rem和vw

在日益发展的移动互联网时代&#xff0c;作为前端开发者&#xff0c;我们必须了解和掌握各种移动端显示效果的适配技术。在众多适配方案中&#xff0c;使用rem和vw进行布局是当前最为流行和普遍使用的两种技术。通过合理运用这两种技术&#xff0c;我们可以让我们的网页在不同尺…

HCIP——前期综合实验

前期综合实验 一、实验拓扑二、实验要求三、实验思路四、实验步骤1、配置接口IP地址2、交换机配置划分vlan10以及vlan203、总部分部&#xff0c;骨干网配置OSPF分部总部骨干网 4、配置BGP建立邻居关系总部骨干网分部 5、发布用户网段6、将下一跳改为本地7、允许AS重复8、重发布…

揭秘!头条百科词条创建全过程及技巧解析

随着互联网时代的到来&#xff0c;人们获取信息的方式越来越便捷。作为国内领先的信息平台&#xff0c;头条百科成为了很多人查阅知识的首选。然而&#xff0c;如何在头条上创建百科词条&#xff0c;让更多人了解和熟知自己呢&#xff1f;本文伯乐网络传媒将为您揭开这个谜团&a…

何恺明把神经网络做深了,谷歌把神经网络的入口拉大了,又深又大,才成为今天的大模型

openai chatgpt 相关_个人渣记录仅为自己搜索用的博客-CSDN博客 大神回归学界&#xff1a;何恺明宣布加入 MIT 如今大模型都在使用的 transformer 的编码器和解码器&#xff0c;里面都有源自 ResNet 的残差链接。 「在 ResNet 之后就可以有效地训练超过百层的深度神经网络&…

Windows 实例如何开放端口

矩池云 Windows 实例相比于 Linux 实例&#xff0c;除了在租用机器的时候自定义端口外&#xff0c;还需要在 Windows防火墙中添加入口规则。接下来将教大家如何设置 Windows 防火墙&#xff0c;启用端口。 租用成功后通过 RDP 链接连接服务器&#xff0c;然后搜索防火墙&#x…

uniapp使用getStorage对属性赋值无效

1正常set(get)storage都是可以正常使用的 2.但对属性进行赋值的时候&#xff0c;却发现this.name并没有发生变化 3. 在里面打印this发现&#xff0c;在set*getStorage中并不能拿到this. 4.优化代码 这样就可以给this.name成功赋值

pinia 状态管理器详细文档记录,如何使用pinia看着一篇就够了!!!

目录 安装Pinia 定义store 1.option对象写法&#xff1a; 2.Setup 函数写法 使用store 接下来细化一下pinia的三大核心概念 state、action、getter 一、state 访问 state 重置 state 变更 state 替换 state 订阅 state 二、Getter 访问其他 getter 向 getter 传递…

116、你是如何理解Spring事务的传播机制的?底层是如何实现的?

你是如何理解Spring事务的传播机制的&#xff1f;底层是如何实现的&#xff1f; 一个线程在运行过程中&#xff0c;可能会连续调用好几个方法&#xff0c;在调用某一个方法时&#xff0c;可能就开启了一个Spring事务&#xff0c;那么在调用接下来的方法时&#xff0c;到底是共用…

【C++】二叉搜索树的原理及实现

简介 二叉搜索树(Binary Search Tree&#xff0c;BST)是一种常用的数据结构&#xff0c;本文将介绍二叉搜索树的原理与特性&#xff0c;并给出C代码实现&#xff0c;最后对其性能进行详细的分析。 文章目录 简介 一、二叉搜索树的概念 二、二叉搜索树的操作及实现 2、1 二叉搜…

01|Oracle学习(监听程序、管理工具、PL/SQL Developer、本地网络服务介绍)

基础概念 监听程序&#xff1a;运行在Oracle服务器端用于侦听客户端请求的程序。 相当于保安&#xff0c;你来找人&#xff0c;他会拦你&#xff0c;问你找谁。他去帮你叫人过来。 配置监听程序应用场景 Oracle数据库软件安装之后没有监听程序&#xff08;服务&#xff09;…

pdf阅读器哪个好用?这个阅读器别错过

pdf阅读器哪个好用&#xff1f;PDF是一种流行的文件格式&#xff0c;可以保留文档的原始格式、布局和字体。与其他文档格式相比&#xff0c;PDF在不同设备和操作系统上的显示效果更为一致&#xff0c;确保文档内容的准确性和可读性。在阅读一些PDF文件的时候&#xff0c;使用一…

文本怎么用手机生成二维码?二维码在线文本码制作技巧

现在二维码可以展示的内容越来越丰富&#xff0c;比如文本就是很常见的一种形式。编辑好文本内容之后&#xff0c;将文字内容添加到二维码中&#xff0c;其他人扫码就可以获取到文字内容&#xff0c;那么文本二维码该如何制作呢&#xff1f;想要制作二维码&#xff0c;那么可以…

全网最牛,postman接口测试-高级应用实战(总结)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 流程控制 流程控…

【Excel自动化办公】openpyxl如何实现Excel超链接批量化设置?

Python是一种高效的编程语言&#xff0c;它可以方便地处理各种文件格式&#xff0c;包括Excel。 在Excel中&#xff0c;超链接是一种非常有用的功能&#xff0c;它可以让用户快速跳转到其他工作表或其他文件中的特定单元格。 在本文中&#xff0c;我们将介绍如何使用Python来…

openpnp - Enable Visual Homing

文章目录 openpnp - Enable Visual Homing概述笔记视觉归零设置END openpnp - Enable Visual Homing 概述 设备已经完全通过openpnp的校验了. 当时发现一个问题, 视觉归零如果使能, 就会使主校准点和次校准点的位置发生变化, 导致顶部相机十字不能准确的落在主/次校准点上. 当…