设计模式 - 行为型考点模式:责任链模式(概述 | 案例实现 | 优缺点 | 使用场景)

news2024/9/29 9:26:16

目录

一、行为型模式

1.1、责任链模式

1.1.1、概述

1.1.2、案例实现

1.1.3、优缺点

1.1.4、使用场景


一、行为型模式


1.1、责任链模式

1.1.1、概述

为了避免请求发送者和多个请求处理者耦合在一起,就将所有请求处理者通过前一个对象记住下一个对象的引用的方式形成一条链;当有请求到来时,可以将请求沿着这条链传递,知道有对象能处理他为止.

例如,公司员工请假,可以批假的领导有小组组长、部门经理、总经理,但是每个领导比准的天数不同,那么员工请假时,就需要记住每一个领导的能请假的天数,十分不方便,但是通过责任链模式,你就可以直接把假条先交给能处理天数最少的人即可,如果小组组长处理不了,小组组长因为持有 部门经理 的引用,就可以找到他,让他处理..... 以此类推,直到找到能处理这个假条的领导为止.

责任链模式主要包含以下角色:

  • 抽象处理者:定义一个处理请求的接口,包含抽象处理方法并持有下一个处理者的引用.
  • 具体处理者:实现抽象处理者的处理方法,判断当前处理者能否处理请求,如果可以就处理,不可以就交给下一个处理者处理.(例如上述的,小组组长、部门经理、总经理)
  • 客户类:创建处理链,并向链头的具体处理者对象提交请求,他不关心具体的处理细节和请求的传递过程.

1.1.2、案例实现

实现上述案例.

/**
 * 请假条类
 */
public class LeaveRequest {

    //请假人姓名
    private String name;
    //请假天数
    private int num;
    //请假原因
    private String reason;

    public LeaveRequest(String name, int num, String reason) {
        this.name = name;
        this.num = num;
        this.reason = reason;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    public String getReason() {
        return reason;
    }

    public void setReason(String reason) {
        this.reason = reason;
    }
    
}
/**
 * 抽象处理者
 */
public abstract class Handler {

    //请假天数
    protected static final int ONE_DAY = 1;
    protected static final int THREE_DAY = 3;
    protected static final int SEVEN_DAY = 7;

    //各级领导能处理请假天数区间
    private int numStart;
    private int numEnd;

    //领导的领导
    private Handler nextHandler;

    /**
     * 领导处理请假天数区间
     * @param numStart
     * @param numEnd
     */
    public Handler(int numStart, int numEnd) {
        this.numStart = numStart;
        this.numEnd = numEnd;
    }

    public void setNextHandler(Handler nextHandler) {
        this.nextHandler = nextHandler;
    }

    /**
     * 提交请假请求
     */
    public final void submit(LeaveRequest request) {
        if(request.getNum() <= numEnd) {
            this.handlerLeave(request);
        } else if(this.nextHandler != null) {
            nextHandler.submit(request);
        } else {
            System.out.println("请假天数超过上限!");
        }
    }

    protected abstract void handlerLeave(LeaveRequest request);

}
/**
 * 具体处理者: 小组组长
 */
public class GroupLeader extends Handler {

    /**
     * 小组长所能处理的请假天数区间
     */
    public GroupLeader() {
        super(0, ONE_DAY);
    }

    @Override
    protected void handlerLeave(LeaveRequest request) {
        System.out.println(request.getName() + "请假 " + request.getNum() + " 天," +
                request.getReason());
        System.out.println("小组长审批通过");
    }

}
/**
 * 具体处理者: 部门经理
 */
public class Manager extends Handler {

    /**
     * 经理所能处理的请假天数区间
     */
    public Manager() {
        super(ONE_DAY, THREE_DAY);
    }

    @Override
    protected void handlerLeave(LeaveRequest request) {
        System.out.println(request.getName() + "请假 " + request.getNum() + " 天," +
                request.getReason());
        System.out.println("部门经理审批通过");
    }

}
/**
 * 具体处理者: 总经理
 */
public class GeneralManager extends Handler {

    /**
     * 经理所能处理的请假天数区间
     */
    public GeneralManager() {
        super(THREE_DAY, SEVEN_DAY);
    }

    @Override
    protected void handlerLeave(LeaveRequest request) {
        System.out.println(request.getName() + "请假 " + request.getNum() + " 天," +
                request.getReason());
        System.out.println("总经理审批通过");
    }

}
/**
 * 客户类
 */
public class Client {

    public static void main(String[] args) {
        //1.假条
        LeaveRequest request1 = new LeaveRequest("李白", 1, "这几天要出诗集~");
        LeaveRequest request2 = new LeaveRequest("杜甫", 3, "生病了,身体不适~");
        LeaveRequest request3 = new LeaveRequest("龙洋静", 6, "着急结婚!");

        //2.责任链关系
        GroupLeader groupLeader = new GroupLeader();
        Manager manager = new Manager();
        GeneralManager generalManager = new GeneralManager();

        groupLeader.setNextHandler(manager);
        manager.setNextHandler(generalManager);

        //3.提交假条
        groupLeader.submit(request1);
        System.out.println("===============");
        groupLeader.submit(request2);
        System.out.println("===============");
        groupLeader.submit(request3);
    }

}

执行结果如下:

1.1.3、优缺点

优点:

  1. 解耦合:降低了发送请求者和处理请求者的耦合度.
  2. 满足开闭原则:可以根据业务需求,新增请求处理类.
  3. 增强了对象指派责任的灵活性:当工作流程发生变化,可以动态的改变链内成员或者修改他们的次序,也可以动态的新增和删除责任.
  4. 简化了对象链接:一个对象只需要持有下一个后继者的引用,不需要保持其他所有处理者的引用,避免了众多的 if else 语句.
  5. 满足单一职责:每个类只需要处理自己的工作,不能处理就交给下一个对象完成.

缺点:

不能保证每一个请求一定被处理:因为请求没有明确的接收者,因此不能保证他一定被处理,该请求可能传到链末也得不到处理.

性能影响:如果责任链较长,请求的处理可能涉及到多个对象,性能会有所损耗.

复杂度:责任链的合理性全靠客户端来保证,增加了客户端的复杂度.

1.1.4、使用场景

1. 多个对象可以处理同一个请求,但具体由哪个对象处理则在运行时动态决定.

2. 请求者不明确要对哪一个对象进行提交申请.

例如像公司职级审批流的设定.

例如用户找回密码需要一步步校验的密保信息.

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

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

相关文章

飞行文本动画效果

效果展示 JavaScript 知识点 textContent.replace 方法运用anime.min.js 插件运用 实现整体页面布局 <section><p class"text">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Impedit suscipitiure explicabo delectus laborum archite…

AVS3:DMVR

AVS3中引入了解码端运动矢量修正&#xff08;DMVR,Decoder side Motion Vector Refinement&#xff09;技术&#xff0c;AVS3中的DMVR技术和G.266/VVC类似&#xff0c;它可以在解码端生成运动参数从而减少传输运动参数的码率开销。它的基本思想是将skip/direct模式生成的前后向…

ArcGIS/GeoScene脚本:基于粒子群优化的支持向量机回归模型

参数输入 1.样本数据必须包含需要回归的字段 2.回归字段是数值类型 3.影响因子是栅格数据&#xff0c;可添加多个 4.随机种子可以确保每次运行的训练集和测试集一致 5.训练集占比为0-1之间的小数 6.迭代次数&#xff1a;迭代次数越高精度越高&#xff0c;但是运行时间越长…

MODBUS-RTU通信协议功能码+数据帧解读(博途PLC梯形图代码)

MODBUS通信详细代码编写,请查看下面相关链接,这篇博客主要和大家介绍MODBUS协议的一些常用功能码和具体数据帧解析,以便大家更好的理解MODBUS通信和解决现场实际问题。 S7-1200PLC MODBUS-RTU通信 博途PLC 1200/1500PLC MODBUS-RTU通讯_博图modbus rtu通讯实例-CSDN博客1、…

博弈论——动态博弈

动态博弈 0 引言 前面一篇文章介绍了博弈过程中的三个分类&#xff1a;静态博弈、动态博弈、重复博弈。今天具体讲讲动态博弈的处理方法。 博弈论——博弈过程 1 概念 首先还是介绍一下动态博弈的概念&#xff0c;即博弈中各博弈方的选择和行动不仅有先后次序&#xff0c;而…

USB协议层数据格式

USB协议 1. 硬件拓扑结构2. 协议层2.1 字节/位传输顺序2.2 SYNC域2.3 包格式2.3.1 PID域2.3.2 令牌包(Token)2.3.3 数据包2.3.4 握手包 2.4 传输细节2.4.1 传输(Transfer)和事务(Transaction)2.4.2 过程(stage)和阶段(phase)2.4.3 批量传输2.4.4 中断传输2.4.5 实时传输2.4.6 控…

点云采样方法

随机采样&#xff0c;网格采样&#xff0c;均匀采样&#xff0c;集合采样。 网格采样&#xff1a;用规则的网格对点进行采样&#xff0c;不能精确的控制采样点的数量 均匀采样&#xff1a;均匀的采样点云中的点&#xff0c;由于其鲁棒性(系统的健壮性)而更受欢迎 点云降采样…

Jetpack:004-如何使用文本组件

文章目录 1. 概念介绍2. 使用方法2.1 通用参数2.2 专用参数 3. 示例代码4. 内容总结 我们在上一章回中介绍了Jetpack组件在布局中的对齐方式&#xff0c;本章回中主要介绍文 本组件的使用方法。闲话休提&#xff0c;让我们一起Talk Android Jetpack吧 1. 概念介绍 我们在本章…

分库分表(3)——ShardingJDBC实践

一、ShardingSphere产品介绍 Apache ShardingSphere 是一套开源的分布式数据库中间件解决方案组成的生态圈&#xff0c;它由 JDBC、Proxy 和 Sidecar&#xff08;规划中&#xff09;这 3 款相互独立&#xff0c;却又能够混合部署配合使用的产品组成。 它们均提供标准化的数据分…

【Java 进阶篇】CSS盒子模型详解

CSS盒子模型是网页布局的基础之一&#xff0c;它定义了HTML元素在页面上的占用空间和相互关系。理解CSS盒子模型对于构建各种类型的网页布局至关重要。在本文中&#xff0c;我们将深入探讨CSS盒子模型的各个方面&#xff0c;包括盒子模型的概念、属性和如何使用它们来控制元素的…

S7-1200与力控通过S7协议通讯

测试环境&#xff1a;Win10、力控7.2SP3、1214DCDCDC 博途工控人平时在哪里技术交流博途工控人社群 博途工控人平时在哪里技术交流博途工控人社群 在画面管理中&#xff0c;有种弹出画面&#xff0c;也就是窗口提示画面&#xff0c; 1-PLC端配置 PLC IP设置为192.168.2.10 …

从0开始学go第六天

方法一&#xff1a;gin获取querystring参数 package main//querystring import ("net/http""github.com/gin-gonic/gin" )func main() {r : gin.Default()r.GET("/web", func(c *gin.Context) {//获取浏览器那边发请求携带的query String参数//…

linux中安装RocketMQ以及dashboard

前提&#xff1a; 需要安装jdk8 上传下面的文件到服务器中 新建目录 mkdir rocketmq 将下载后的压缩包上传到阿里云服务器或者虚拟机中去&#xff0c;并解压 unzip rocketmq-all-4.9.2-bin-release.zip 配置环境变量 vim /etc/profile 配置内容&#xff1a; export NAM…

解决方案|法大大电子签助力食品行业打通内外部高效协作链路

对食品行业来说&#xff0c;技术是保证食品安全的重要前提和基础。数字化转型就是要将传统的食品行业与新技术相结合&#xff0c;从而达到改善传统食品生产模式、提高传统食品生产效率的目的。通过数字化技术来推动企业从原材料采购、产品设计、生产、营销、物流、合同管理等全…

代码随想录算法训练营第四十九天 | 139.单词拆分、关于多重背包,你该了解这些!

139.单词拆分 视频讲解&#xff1a;动态规划之完全背包&#xff0c;你的背包如何装满&#xff1f;| LeetCode&#xff1a;139.单词拆分_哔哩哔哩_bilibili 代码随想录 &#xff08;1&#xff09;代码 关于多重背包&#xff0c;你该了解这些&#xff01; 链接&#xff1a; 代码…

浏览器详解(四) 渲染

大家好&#xff0c;我是半虹&#xff0c;这篇文章来讲浏览器渲染 1、基本介绍 浏览器是多进程多线程的架构&#xff0c;包括有浏览器进程、渲染器进程、GPU 进程、插件进程等 在上篇文章中我们介绍过浏览器进程&#xff0c;作为浏览器主进程&#xff0c;负责浏览器基本界面的…

【轻松玩转MacOS】指引篇:这9篇指南助你轻松上手

引言 亲爱的读者&#xff0c;欢迎来到《轻松玩转MacOS》&#xff01;这里是专为MacOS新手打造的使用教学专栏&#xff0c;无论您是从Windows转投Mac的初学者&#xff0c;还是对MacOS操作略知一二但希望更进一步的朋友&#xff0c;都能在这里找到您需要的答案。 正文 1、基本…

xshell环境配置

如何下载以及安装xshellxftp教育优惠版本及配置anaconda环境 下载教育优惠版本 下载网址&#xff1a;https://www.xshell.com/zh/free-for-home-school/ 注意安装路径&#xff0c;可以更改&#xff0c;但是不可以新建文件夹&#xff0c;如果有想建在别的地方的可以提前建好 …

安装libX11过程记录

目录 编译平台 准备工作 参考信息源 安装步骤 1 建立文件夹/opt/libX11target 2 定义环境变量PKG_CONFIG_PATH 3 安装xproto-7.0.31 3.1 下载xproto-7.0.31 3.2 解压 3.3 进入解压后的文件夹 3.4 建立build文件夹 3.5 cd build 3.6 配置 3.7 make 3.8 sudo ma…