二十二、责任链模式

news2024/12/23 6:47:43

目录

      • 1、使用demo演示责任链模式
      • 2、传统方案解决oa系统审批
      • 3、传统方案解决oa系统审批存在的问题
      • 4、职责链模式基本介绍
      • 5、职责链模式原理类图
      • 6、职责链模式解决oa系统采购审批
      • 7、职责链模式的注意事项和细节
      • 8、职责链模式的实际使用场景举例

1、使用demo演示责任链模式

学校oa系统的采购审批项目:需求是
在这里插入图片描述


2、传统方案解决oa系统审批

在这里插入图片描述
在一个类中对教学器材的价格进行判断,然后根据判断调用不同的审批者进行审批


3、传统方案解决oa系统审批存在的问题

  • 客户端这里会使用分支判断来对不用的采购请求进行处理,这样就存在如下问题
    • 如果各个级别的人员审批金额发生变化,客户端也需要相应变化
    • 客户端必须明确知道有多少个审批级别
  • 采购请求和审批人员之间存在强耦合关系,不利于代码的扩展和维护

4、职责链模式基本介绍

职责链模式又称为责任链模式:每个接收者都包含对另一个接收者的引用,如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依次类推


5、职责链模式原理类图

在这里插入图片描述

对职责链模式的说明:

  • Handler:抽象的处理者,定义了一个处理请求的方法,并且聚合了自身
  • ConcreteHandlerA|B:是具体的处理者,处理它自己负责的请求,可以访问它的后继者,如果可以处理当前请求,则处理,否则将该请求交给下个后继者去处理,从而形成一个职责链

6、职责链模式解决oa系统采购审批

1)类图分析
在这里插入图片描述
2)代码实现

// 购买请求
public class PurchaseRequest {

    //
    private int type;

    private float price;

    private int id;

    public PurchaseRequest(int type, float price, int id) {
        this.type = type;
        this.price = price;
        this.id = id;
    }

    public int getType() {
        return type;
    }

    public float getPrice() {
        return price;
    }

    public int getId() {
        return id;
    }
}

// 审批者抽象类
public abstract class Approver {

    Approver approver; // 下一个处理者

    String name;

    public Approver(String name) {
        this.name = name;
    }

    // 设置下一个处理者
    public void setApprover(Approver approver) {
        this.approver = approver;
    }

    // 处理 审批请求的方法,得到一个请求
    public abstract void processRequest(PurchaseRequest purchaseRequest);
}


/**
 *  部门主任
 */
public class DepartmentApprover extends Approver {


    public DepartmentApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() <= 5000) {
            System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");
        } else {
            // 如果不能处理,则让下一个处理者进行处理
            approver.processRequest(purchaseRequest);
        }
    }
}

/**
 * 系主任
 */
public class CollegeApprover extends Approver {


    public CollegeApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() > 5000 && purchaseRequest.getPrice() <= 10000) {
            System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");
        } else {
            // 如果不能处理,则让下一个处理者进行处理
            approver.processRequest(purchaseRequest);
        }
    }
}

/**
 * 副校长
 */
public class ViceSchoolMasterApprover extends Approver {


    public ViceSchoolMasterApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() > 10000 && purchaseRequest.getPrice() <= 30000) {
            System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");
        } else {
            // 如果不能处理,则让下一个处理者进行处理
            approver.processRequest(purchaseRequest);
        }
    }
}
/**
 * 校长
 */
public class SchoolMasterApprover extends Approver {


    public SchoolMasterApprover(String name) {
        super(name);
    }

    @Override
    public void processRequest(PurchaseRequest purchaseRequest) {
        if (purchaseRequest.getPrice() > 30000) {
            System.out.println("请求编号 id = " + purchaseRequest.getId() + "被" + this.name + "处理");
        } else {
            // 如果不能处理,则让下一个处理者进行处理
            approver.processRequest(purchaseRequest);
        }
    }
}

public class Client {

    public static void main(String[] args) {

        PurchaseRequest purchaseRequest = new PurchaseRequest(1, 31000, 1);	DepartmentApprover departmentApprover = new DepartmentApprover("张主任");
        CollegeApprover collegeApprover = new CollegeApprover("李院长");
        ViceSchoolMasterApprover viceSchoolMasterApprover = new ViceSchoolMasterApprover("王副校");
        SchoolMasterApprover schoolMasterApprover = new SchoolMasterApprover("佟校长");

        //需要将各个审批级别的下一个设置好 (处理人构成环形: )
        departmentApprover.setApprover(collegeApprover);
        collegeApprover.setApprover(viceSchoolMasterApprover);
        viceSchoolMasterApprover.setApprover(schoolMasterApprover);
        schoolMasterApprover.setApprover(departmentApprover);

        departmentApprover.processRequest(purchaseRequest);

    }
}

在这里插入图片描述


7、职责链模式的注意事项和细节

  • 将请求和处理分开,实现解耦,提高系统的灵活性
  • 性能收到影响,特别是在链比较长的时候。因此需要控制链中最大节点数量,一般通过在Handler中设置一个
    最大节点数量,在setNext方法中判断是否已经超过阈值,超过则不允许建立改节点
  • 由于采取了链的方式,所以调试逻辑比较复杂

8、职责链模式的实际使用场景举例

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

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

相关文章

讯飞星火认知大模型升级体验

今天讯飞星火新版本已更新至现网&#xff0c;增加了多模态、插件等很多功能~,阅读原文可以申请体验 官网地址&#xff1a;https://xinghuo.xfyun.cn/ 多模态能力 多模理解&#xff08;图片&#xff09;&#xff1a;支持用户图片输入&#xff0c;针对图片内容进行视觉问答。 …

Thread.sleep()不释放锁 Object.wait()释放锁

sleep()方法 sleep()方法是线程类&#xff08;Thread&#xff09;的静态方法&#xff0c;让调用的线程进入指定时间睡眠状态&#xff0c;使得当前线程进入阻塞状态。 当线程获取锁时&#xff0c;sleep()方法不会释放对象锁 wait()方法 wait()方法是Object类里的方法&#xff0c…

12个有趣的css库

12个有趣的css库 1. Animate Animate 是一个即用型跨浏览器动画库&#xff0c;可在我们的 Web 项目中使用。非常适合强调、主页、滑块和注意力引导提示。 2. Magic Magic里包含了一组简单的动画&#xff0c;可以在我们的Web或app项目中使用。 3. Animista Animista 是一个 …

【Linux系统编程】23.孤儿进程、僵尸进程、wait、waitpid

目录 孤儿进程 测试代码1 测试结果 僵尸进程 测试代码2 测试结果 wait 参数*wstatus 返回值 测试代码3 测试结果 测试代码4 测试结果 测试代码5 测试结果 waitpid 参数pid 参数*wstatus 参数options 返回值 测试代码6 测试结果 测试代码7 测试结果 测…

Zemax2019中文设置

做软件教程啥时候都不能少了切换中文版啊~ 正常打开软件&#xff1a; 点击setup 中的preference 弹出窗口&#xff1a; 选择general 在language的下拉窗口中选择&#xff0c;中文 效果&#xff1a;

实验篇——亚细胞定位

实验篇——亚细胞定位 文章目录 前言一、亚细胞定位的在线网站1. UniProt2. WoLFPSORT3. BUSCA4. TargetP-2.0 二、代码实现1. 基于UniProt&#xff08;不会&#xff09;2. 基于WoLFPSORT后续&#xff08;已完善&#xff0c;有关代码放置于[python爬虫学习&#xff08;一&#…

[保研/考研机试] 杨辉三角形 西北工业大学复试上机题 C++实现

题目描述 Time Limit: 1000 ms Memory Limit: 256 mb 输入n值&#xff0c;使用递归函数&#xff0c;求杨辉三角形中各个位置上的值。 输入描述: 一个大于等于2的整型数n 输出描述: 题目可能有多组不同的测试数据&#xff0c;对于每组输入数据&#xff0c; 按题目的要求输…

Java笔记-kafka

修改kafka的server.properties配置 概念 单播 一个消费组的消费者们只有一个能消费到消息。类似queue队列。 多播 不同的消费组的消费者能重复消费到消息&#xff0c;类似publish-subscribe模式 消费组偏移 kafka和别的消息中间件不一样&#xff0c;不同组可以重复消费&a…

Grafana监控 Redis Cluster

Grafana监控 Redis Cluster 主要是使用grafana来实现监控&#xff0c;grafana可以对接多种数据源&#xff0c;在官网中可以找到Redis数据源&#xff0c;需要安装redis data source插件。当然也可以利用Prometheus来做数据源&#xff0c;下面分别记录一下这两种数据源的安装配置…

前后端分离------后端创建笔记(04)前后端对接

本文章转载于【SpringBootVue】全网最简单但实用的前后端分离项目实战笔记 - 前端_大菜007的博客-CSDN博客 仅用于学习和讨论&#xff0c;如有侵权请联系 源码&#xff1a;https://gitee.com/green_vegetables/x-admin-project.git 素材&#xff1a;https://pan.baidu.com/s/…

“MongoDB基础知识【超详细】

"探索MongoDB的无边之境&#xff1a;沉浸式数据库之旅" 欢迎来到MongoDB的精彩世界&#xff01;在这个博客中&#xff0c;我们将带您进入一个充满创新和无限潜力的数据库领域。无论您是开发者、数据工程师还是技术爱好者&#xff0c;MongoDB都将为您带来一场令人心动…

网络安全威胁与防御策略

第一章&#xff1a;引言 随着数字化时代的快速发展&#xff0c;网络已经成为人们生活和工作中不可或缺的一部分。然而&#xff0c;网络的广泛应用也引发了一系列严峻的网络安全威胁。恶意软件、网络攻击、数据泄露等问题层出不穷&#xff0c;给个人和企业带来了巨大的风险。本文…

UI美工设计岗位的基本职责概述(合集)

UI美工设计岗位的基本职责概述1 1、有良好的美术功底、设计新颖&#xff0c;整体配色及设计创意理念&#xff0c;能够独立完成整个网站页面设计及制作; 2、熟练运用DIV CSS&#xff0c;HTML 设计制作网页 ; 3、熟练运用Photoshop,Dreamweaver,Coreldraw(或Illustrator),Fla…

7-2 计算物体自由下落的距离

一个物体从100米的高空自由落下。编写程序&#xff0c;求它在前3秒内下落的垂直距离。设重力加速度为10米/秒2。 输入格式: 本题目没有输入。 输出格式: 按照下列格式输出 height 垂直距离值结果保留2位小数。 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB …

异常(下)Java常见异常,异常的使用原则

文章目录 前言一、Java常见异常 1.常见异常2.实例展示二、异常的使用原则总结 前言 该文介绍了Java的一些常见异常&#xff0c;并给出对应的例子进行解释。介绍异常的使用原则&#xff0c;即创建&#xff0c;抛出异常的编程规范。 一、Java常见异常 前要&#xff1a;Java API中…

实训五:用户和组账号管理

实训五&#xff1a;用户和组账号管理 2017 年 X 月 X 日 今日公布 四&#xff1a;实训内容 用root用户登录系统&#xff0c;查看用户账号文件/etc/passwd和口令文件/etc/shadow的内容&#xff0c;注意观察其存储格式、各账户所使用的Shell、UID、GID等属性信息。 答&#xf…

ITIL4—度量和报告实践

1. 关于本文 本文为度量和报告实践提供了实用指南&#xff0c;分为五个主要部分&#xff0c;涵盖&#xff1a; 本实践的基本信息本实践相关的流程和活动&#xff0c;及其在服务价值链中的作用参与本实践的组织和人员支持本实践的信息和技术合作伙伴和供应商在本实践中的注意事…

【构造】CF1853D

Problem - D - Codeforces 题意&#xff1a; 思路&#xff1a; Code&#xff1a; #include <bits/stdc.h>using i64 long long;const int N 1e6 10;int ans[N];void solve() {int n;std::cin >> n;std::vector<std::pair<int,int> > a(n 1);for …

如何高效进行项目任务管理?掌握这些神器助你一臂之力

任务管理是项目管理中的重点部分&#xff0c;关系到项目能否顺利的完成。项目经理该如何进行项目任务管理呢&#xff1f; 一、项目任务管理中的挑战 二、项目任务管理指南 三、项目任务管理神器 首先我们需要先清楚当下企业在项目任务管理中遇到的挑战。 一、项目任务管理中的…

【Kafka】2.在SpringBoot中使用官方原生java版Kafka客户端

目 录 1. 新建一个消息生产者2. 新建一个消息消费者3. 测 试 在开始之前&#xff0c;需要先做点准备工作&#xff0c;用 IDEA 新建一个 Maven 项目&#xff0c;取名 kafka-study&#xff0c;然后删掉它的 src 目录&#xff0c;接着在 pom.xml 里面引入下面的依赖。这个项目的作…