设计模式—责任链模式

news2024/9/22 1:04:32

一、待解决问题: 减少代码中 if else 语句,降低代码圈复杂度或深度,增强可读性。
1、需求背景: 采购订单创建,需要验证采购员、物料、供应商、供应商的银行账号等信息。如采购员权限到期、或供应商失效等问题,都无法下单。
2、代码如下:

public class PurchaseOrderHandler {
    public boolean isBuyerPermissionSupport(PurchaseOrderEntity orderEntity) {
    }

    public boolean isSupplierValid(PurchaseOrderEntity orderEntity) {
    }

    public boolean isItemAllowed(PurchaseOrderEntity orderEntity) {
    }

    public boolean isSupplierBankAccountValid((PurchaseOrderEntity orderEntity) {
    }

    public String createPurchaseOrder(PurchaseOrderEntity orderEntity) {
        if (!isBuyerPermissionSupport(orderEntity)) {
            return "buyer has no permission";
        }
        if (!isItemAllowed(orderEntity)) {
            return "item is not allowed";
        }
        if (!isSupplierValid(orderEntity)) {
            return "supplier is not valid";
        }
        if (!isSupplierBankAccountValid(orderEntity)) {
            return "supplier bank account is not valid";
        }
        /**
         * 创建逻辑省略。。。。。。
         */
        return "create Success";
    }
}

学习使用责任链模式后优化:

public abstract class Handler {
    public Handler successor;

    public abstract boolean isValid(PurchaseOrderEntity orderEntity);

    public void setSuccessor(Handler handler) {
        successor = handler;
    }
}

public class BuyerHandler extends Handler{
    @Override
    public boolean isValid(PurchaseOrderEntity orderEntity) {
        if ("xxxBuyer".equals(orderEntity.getBuyer())) {
            return false;
        } else {
            return successor.isValid(orderEntity);
        }
    }
}

public class ItemHandler extends Handler{
    @Override
    public boolean isValid(PurchaseOrderEntity orderEntity) {
        if ("xxxxItem".equals(orderEntity.getItem())) {
            return false;
        } else {
            return successor.isValid(orderEntity);
        }
    }
}
/**省略供应商和供应商银行账号的校验类 **/

public class PurchaseOrderHandler {
    public String createPurchaserOrder(PurchaseOrderEntity orderEntity) {
        Handler buyerHandler = new BuyerHandler();
        Handler itemHandler = new ItemHandler();
        Handler supplierHandler = new SupplierHandler();
        Handler supplierBankAccountHandler = new SupplierBankAccountHandler();
        Handler lastHandler = new SupplierHandler();
        buyerHandler.setSuccessor(itemHandler);
        itemHandler.setSuccessor(supplierHandler);
        supplierHandler.setSuccessor(supplierBankAccountHandler);
        supplierBankAccountHandler.setSuccessor(lastHandler);

        if (!buyerHandler.isValid(orderEntity)) {
            return "purchase order create error.";
        }
        return "create Success";
    }
 }

3、分析:使用责任链模式,将整体的校验流程和具体校验点逻辑实现分离,但是每增加一个校验点,就要新增一个实现类。

二、责任链模式:
为避免发送者与多个请求处理者耦合在一起,将所有的请求处理者通过前一对象记住其下一个对象的引用而连城一条链。当请求发生时,可将请求沿着这条链传递,直接有对象处理它为止。

备注:从这个概念看,责任链模式主要用于解决为请求找到合适的处理对象。经典案例是请假问题,如请假3天组长审批,5天项目经理审批,7天部长审批。组长、项目经理、部长属于不同的对象。

1、主要角色:
抽象处理者(handler):包含处理请求的接口、抽象处理方法和后继节点。
具体处理者(Concrete handler):继承实现抽象处理者并实现请求的接口。可以处理请求则处理,不能处理则转给后继节点。
客户端角色(client):创建处理链,并向具体的处理对象提交请求。
类图:
在这里插入图片描述
2、优点:
1、减低对象之间的耦合度。
2、增强系统的可扩展性,满足开闭原则。
3、简化了处理对象的链接,避免过多的 if else 语句。
4、责任分担。每个类只处理自己的逻辑,明确责任范围,符合类的单一职责原则。
3、缺点:
1、每个处理对象要创建一个类,造成类过多。
2、使用客户端角色创建责任链。如果责任链的继任者设置错误,可能造成循环调用。
3、当责任链过长,请求处理涉及多个处理对象,无法使用并发,系统性能受到影响。

三、实际项目感悟:
1、责任链模式主要用于解决为请求找到合适的处理对象。本文中的案例使用责任链解决校验逻辑多造成的 if else 语句过多问题,可能并不是一个好的主意。因为这样造成了过多的类对象,并且不相关校验逻辑不能使用并发校验。这种场景需要找到一个更合适的方案解决。
2、责任链会使代码增多。

学习自B站课程: https://www.bilibili.com/video/BV1Np4y1z7BU?p=105

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

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

相关文章

python机器学习——机器学习相关概念 特征工程

目录 机器学习特征工程1.特征抽取2.特征处理2.1 归一化:传统精确小数据2.2 标准化:大多数情况 3.数据降维3.1特征选择3.2主成分分析PCA 案例:超市订单分析 机器学习 监督学习:输入数据有特征有标签,即有标准答案 分类&…

chatgpt赋能python:Python求累加求和指南

Python求累加求和指南 Python是一种简单而强大的编程语言,从事编程工作的人大多都对它有一定的了解。它具有开发复杂应用程序的强大功能,同时也可以被用作数据处理和分析等用途。其中一个最常见的任务就是累加求和,今天我们将介绍如何在Pyth…

Redis 集合相关命令

Redis 支持多种数据结构,比如 字符串、列表、集合、有序集合 和 哈希 等数据结构。本次我整理了关于 集合 相关的命令,也就是关于 Sets 相关的命令,如下图。 上图中用红色圈中的部分,就是关于 集合 相关的命令。如果想要在 Redis …

JDBC小记——基础入门

目录 JDBC概念 JDBC入门 1. 导入数据库的驱动jar包 2. 加载驱动jar包 3. 获取连接对象 4. 获取操作对象 5.执行SQL语句 6.释放资源 IDEA连接数据库 结果集对象 登录练习 JDBC概念 Java DataBase Connectivity 即 Java数据库连接 JDBC,其实就是Java定义…

第7章 Scala集合

第7章 Scala集合 7.1 简介 ​ ​ scala.collection.immutable ​ scala.collection.mutable ​ 7.2 数组 ​ 不可变数组 package chapter07object Test01_ImmutableArray {def main(args: Array[String]): Unit {// 1. 创建数组val arr: Array[Int] new Array[Int](10…

【AUTOSAR】AUTOSAR开发工具链(二)----TASKING库的封装

1、集成工程 步骤: 拷贝模块代码: 将源工程的所有模块代码拷贝到库工程,将源工程拷贝一份,并删除不必要的文件作为释放工程,完成结果如下图: 源工程(左)VS库工程(中&am…

[CUDA][Ubuntu]如何卸载cuda和cudnn和nvidia driver

百度有很多牛鬼蛇神的办法,试了一晚上,都不行。 包括:通过安装方式卸载,我tm根本不知道当初这个机器是怎么安装的cuda,我怎么卸载??? 通过删除文件夹和自带uninstall程序&#xff…

安卓蓝牙协议数据包格式

本文解析蓝牙传输的数据包格式,目的是对蓝牙的各个层次的协议有更深的理解。 bit数据流格式 在讲数据报文之前,必须了解协议中对数据的BIT排序的规定,在协议中规定数据包或者PDU都是以Little Endian format(小端模式)存放,也就是…

数据库信息速递 - 将可观测性带到现代数据堆栈 (译)

开头还是介绍一下群,如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题,有需求都可以加群群内有各大数据库行业大咖,CTO,可以解决你的问题。加群请联系 liuaustin3 ,在新加的朋友会分到2群(共…

Layui基础入门

一、引言 1.1 介绍 官网&#xff1a;<https://www.layui.com/ > 这个不维护了 看下面这个 https://www.layuiweb.com/ 在官网首页&#xff0c;可以很方便的下载LayUI LayUI 是一款经典模块化前端 UI 框架&#xff0c;我们只需要定义简单的HTML、CSS、JS即可实现很复杂的前…

小鲜肉语录

马上端午放假了&#xff0c;今天不聊技术&#xff0c;聊点轻松的。 一、 和老公、小鲜肉周末出去玩&#xff0c;路上闲聊。老公提到小鲜肉在他们班成绩大概是第四名。 我说&#xff1a;我小学五年级的时候我们我们班60个人我排第四。你们班不到30个人。这么算你成绩不如我小时候…

Qt编写跨平台的推流工具(支持win/linux/mac/嵌入式linux/安卓等)

一、前言 跨平台的推流工具当属OBS最牛逼&#xff0c;功能也是最强大的&#xff0c;唯一的遗憾就是多路推流需要用到插件&#xff0c;而且CPU占用比较高&#xff0c;默认OBS的规则是将对应画布中的视频画面和设定的音频一起重新编码再推流&#xff0c;意味着肯定占用不少CPU资…

【解决】笔记本电脑wifi无法访问网站的各种情况

本文适用于 mac 以及 windows 等操作系统 场景 手机可以连接wifi&#xff0c;电脑连接却无法访问左下角wifi图标为小地球可以使用app&#xff0c;无法访问网站其他 方式一 Win10任务栏中的网络变成小地球&#xff0c;无WIFI列表显示&#xff0c;应该&#xff1a; winR , 输入…

MATLAB计算程序运行所需的时间

在使用MATLAB进行计算时&#xff0c;用户有时需要了解程序运行所花费的四件&#xff0c;以此来评价程序的执行效率&#xff0c;从而对代码进行优化 可以使用3种方法来得到程序运行所需要的时间 1.使用tic和toc命令 将tic和toc命令相结合来得到程序的运行时间 ①tic命令&…

SAP CAP篇六:为CAP添加Fiori Elements程序(3)

本文目录 本系列之前的文章本篇之前的运行效果修改pom.xml添加新的Dependency更新plugin 添加新的Controller创建index目录添加UiIndexContentProviderFactory.java 添加resources运行结果更新UiIndexContentProviderFactory 代码库 (Gitcode) 本系列之前的文章 本系列之前的文…

文学创作的数学原理——5年文学阅读的思考

作者 | gongyouliu 编辑 | gongyouliu 我从2019年初开始阅读文学作品&#xff0c;到今年差不多5年了&#xff0c;至少也阅读了50本以上的世界名著了&#xff08;如果算「得到」听书上的文学作品&#xff0c;那么至少也有200本以上了&#xff09;&#xff0c;这里面绝大多数都是…

python(10):批量修改文件名

文章目录 1. 使用Python的字符串操作来去除文件名高位的多余零说明代码示例 2. 将文件夹中的文件重命名为递增的数字加上原始文件名的后缀代码运行前后&#xff1a; 1. 使用Python的字符串操作来去除文件名高位的多余零 说明 一个目录下的文件名是6位数字序号加上后缀的格式&…

PaddleSeg在Windows上的配置及人像分隔使用

PaddleSeg是基于飞桨PaddlePaddle开源的端到端图像分割套件&#xff0c;提供语义分割、交互式分割、Matting、全景分割四大分割能力。源代码地址&#xff1a;https://github.com/PaddlePaddle/PaddleSeg&#xff0c;license为Apache-2.0&#xff0c;最新发布版本为2.8。 Window…

借用jQuery发送Http请求的实现(内附源码)

文章目录 一、前言二、jQuery 介绍三、jQuery 下载四、jQuery 使用五、Http客户端DEMO实现 一、前言 最近在解决项目上前同事开发的视频播放器问题&#xff0c;视频播放器是用Qt开发&#xff0c;作为播放插件供Web调用。 播放器与Web的通信方式采用的是Http&#xff0c;数据格…

libevent(1)windows下安装libevent

Socket通信库libevent成熟、稳定、性能高&#xff0c;在unix和windows下都能使用&#xff0c;在证券交易领域也有不少成功的应用&#xff0c;已经用事实证明是非常棒的socket通信库。对我们目前交易系统的unix重构来说&#xff0c;是比较合适的选择 –– 坑少、在证券交易项目中…