用责任链模式改造 if else

news2024/12/25 15:09:47

我的上一篇文章,因为if else 多了,捣鼓很久,今天用责任链模式改造一下。

代码写着写着,if else if 逻辑忘记了,哎。。。-CSDN博客
责任链模式(Chain of Responsibility Pattern)
1. 什么是责任链模式?
责任链模式是一种行为设计模式,它允许请求沿着处理者链传递,直到其中一个处理者处理它。每个处理者都可以决定是否处理请求或者将其传递给链中的下一个处理者。
2. 责任链模式的优点
降低耦合度:请求发送者不需要知道请求的最终处理者是谁,只需要知道请求会被某个处理者处理。
灵活配置处理链:可以根据需要动态地增加或删除处理者,而不影响其他处理者。
增强系统扩展性:新的处理者可以很容易地添加到链中,从而扩展系统的功能。
3. 责任链模式的应用场景
权限控制:多个权限检查器组成一个链,逐级检查用户的权限。
日志处理:多个日志处理器组成一个链,逐级处理日志消息。
支付处理:多种支付方式组成一个链,逐级处理支付请求。
4. 责任链模式的实现
现在如下代码改成 责任链模式

        //代理价>销售价
        if (agentPrice.compareTo(goodsPrice) > 0) {
            isNeedLock=true;
            reason="代理价>销售价";
            reasonType="1";
            log.info("agentPrice.compareTo(goodsPrice) > 0 ");
        }else if (agentPrice.compareTo(BigDecimal.ZERO) > 0) {
            //(销售价-代理价)/代理价<5%
            double num = (goodsPrice.subtract(agentPrice)).divide(agentPrice,6, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal(100)).doubleValue();
            if (num < 5) {
                isNeedLock=true;
                reason="(销售价-代理价)/代理价<5%";
                reasonType="2";
                log.info("agentPrice.compareTo(BigDecimal.ZERO) > 0");
            }
 
        }else if (supplyPrice.compareTo(agentPrice) > 0) {
            isNeedLock = true;
            reason = "供货价大于代理价";
            reasonType = "5";
            log.info(" supplyPrice.compareTo(agentPrice) > 0 ");
        }


 

首先分析需要代码,这里的每一个 if else 都有机会执行,一个执行了,其他的 if else 就不会执行了。

入参需要三个价格,那么可以将这个价格放到一个类里面, 这里执行结果有四种,那么可以创建一个枚举类存放,可以在初始化入参的时候设置为默认枚举。

入参请求和结果类 PriceCheckRequest 

/**
 * @author hds
 */
@Data
public class PriceCheckRequest {
    private BigDecimal goodsPrice;
    private BigDecimal agentPrice;
    private BigDecimal supplyPrice;
    private PriceCheckEnum priceCheckEnum;


    public PriceCheckRequest(BigDecimal goodsPrice, BigDecimal agentPrice, BigDecimal supplyPrice) {
        this.goodsPrice = goodsPrice;
        this.agentPrice = agentPrice;
        this.supplyPrice = supplyPrice;
    }

    public PriceCheckRequest(Product product) {
        this.goodsPrice = Optional.ofNullable(product.getProductPrice()).orElse(BigDecimal.ZERO);
        this.agentPrice = Optional.ofNullable(product.getAgentPrice()).orElse(BigDecimal.ZERO);
        this.supplyPrice = Optional.ofNullable(product.getSupplyPrice()).orElse(BigDecimal.ZERO);
        priceCheckEnum = PriceCheckEnum.DEFAULT;
    }
}

结果枚举类

@Getter
public enum PriceCheckEnum {

/*    request.setNeedLock(true);
            request.setReason("代理价>销售价");
            request.setReasonType("1");

             request.setNeedLock(true);
                request.setReason("(销售价-代理价)/代理价<5%");
                request.setReasonType("2");

                 request.setNeedLock(true);
            request.setReason("供货价大于代理价");
            request.setReasonType("5");
            */

    DEFAULT("0", "", false),
    AGENT_PRICE_GREATER_THAN_SALE_PRICE("1", "代理价>销售价", true),
    SALE_PRICE_DIFFERENCE_PERCENTAGE("2", "(销售价-代理价)/代理价<5%", true),
    SUPPLIER_PRICE_GREATER_THAN_AGENT_PRICE("5", "供货价>代理价", true);

    private final String reasonType;
    private final String reason;
    private final Boolean needLock;

    PriceCheckEnum(String reasonType, String reason, boolean needLock) {
        this.reasonType = reasonType;
        this.reason = reason;
        this.needLock = needLock;
    }

解下类就要创建一个 价格检查的抽象类 

PriceCheckHandler 其中 next 属性是执行 下一个处理器
@Setter
public abstract class PriceCheckHandler {

    protected PriceCheckHandler next;

    public abstract void handle(PriceCheckRequest request);

    public  void check(PriceCheckRequest request){
        if (!request.getPriceCheckEnum().getNeedLock()){
            if (next != null) {
                next.handle(request);
            }
        }
    }
}

代理价大于销售价 处理器

AgentPriceGreaterThanGoodsPriceHandler
public class AgentPriceGreaterThanGoodsPriceHandler extends PriceCheckHandler {

    @Override
    public void handle(PriceCheckRequest request) {
        if (BigDecimalUtil.isGreaterThan(request.getAgentPrice(),request.getGoodsPrice())) {
            request.setPriceCheckEnum(PriceCheckEnum.AGENT_PRICE_GREATER_THAN_SALE_PRICE);
        }
        check(request);
    }
}

供货价大于代理价处理器

SupplyPriceGreaterThanAgentPriceHandler
public class SupplyPriceGreaterThanAgentPriceHandler extends PriceCheckHandler {

    @Override
    public void handle(PriceCheckRequest request) {
        if (BigDecimalUtil.isGreaterThan( request.getSupplyPrice(), request.getAgentPrice())) {
            request.setPriceCheckEnum(PriceCheckEnum.SUPPLIER_PRICE_GREATER_THAN_AGENT_PRICE);
        }
        check(request);
    }
}
(销售价-代理价)/代理价<5% 处理器
AgentPricePercentageDifferenceHandler
public class AgentPricePercentageDifferenceHandler extends PriceCheckHandler {

    @Override
    public void handle(PriceCheckRequest request) {
        if ( BigDecimalUtil.isGreaterThan(request.getAgentPrice(),BigDecimal.ZERO) ) {
            double num = (request.getGoodsPrice().subtract(request.getAgentPrice()))
                    .divide(request.getAgentPrice(), 6, RoundingMode.HALF_UP)
                    .multiply(new BigDecimal(100))
                    .doubleValue();
            if (num < 5) {
                request.setPriceCheckEnum(PriceCheckEnum.SALE_PRICE_DIFFERENCE_PERCENTAGE);
            }
            check(request);
        }
        check(request);
    }
}

默认处理器

DefaultPriceHandler 默认返回价格检查通过,需要把它放在责任链的最后处理器
public class DefaultPriceHandler extends PriceCheckHandler {

    @Override
    public void handle(PriceCheckRequest request) {
        request.setPriceCheckEnum(PriceCheckEnum.DEFAULT);
    }
}

责任链创建类 (简单的建造者模式)

ChainBuilder
public class ChainBuilder {

    private PriceCheckHandler head;

    public static ChainBuilder chainBuilder = new ChainBuilder();
    static {
        chainBuilder.addFirst(new DefaultPriceHandler());
        chainBuilder.addFirst(new AgentPricePercentageDifferenceHandler());
        chainBuilder.addFirst(new SupplyPriceGreaterThanAgentPriceHandler());
        chainBuilder.addFirst(new AgentPriceGreaterThanGoodsPriceHandler());

    }


    public void addFirst(PriceCheckHandler handler) {
        handler.setNext(head);
        head = handler;
    }

    public void process(PriceCheckRequest request) {
        if (head != null) {
            head.handle(request);
        }
    }
}

最后测试


@Slf4j
public class ChainBuilderTest {

    @Test
    public void testChain(){
        Product product = new Product();
        product.setAgentPrice(new BigDecimal("59.00"));
        product.setProductPrice(new BigDecimal("60.00"));
        product.setSupplyPrice(new BigDecimal("50.00"));

        PriceCheckRequest priceCheckRequest = new PriceCheckRequest(product);
        ChainBuilder.chainBuilder.process(priceCheckRequest);
        log.info("商品价格校验结果:{}", JSONUtil.toJsonStr(priceCheckRequest) );

        product.setAgentPrice(new BigDecimal("70.00"));
        product.setProductPrice(new BigDecimal("60.00"));
        product.setSupplyPrice(new BigDecimal("50.00"));
        //AGENT_PRICE_GREATER_THAN_SALE_PRICE
        priceCheckRequest = new PriceCheckRequest(product);
        ChainBuilder.chainBuilder.process(priceCheckRequest);
        log.info("商品价格校验结果:{}", JSONUtil.toJsonStr(priceCheckRequest) );

        product.setAgentPrice(new BigDecimal("60.00"));
        product.setProductPrice(new BigDecimal("60.00"));
        product.setSupplyPrice(new BigDecimal("80.00"));
        //SUPPLIER_PRICE_GREATER_THAN_AGENT_PRICE
        priceCheckRequest = new PriceCheckRequest(product);
        ChainBuilder.chainBuilder.process(priceCheckRequest);
        log.info("商品价格校验结果:{}", JSONUtil.toJsonStr(priceCheckRequest) );

        product.setAgentPrice(new BigDecimal("60.00"));
        product.setProductPrice(new BigDecimal("80.00"));
        product.setSupplyPrice(new BigDecimal("60.00"));
        //DEFAULT
        priceCheckRequest = new PriceCheckRequest(product);
        ChainBuilder.chainBuilder.process(priceCheckRequest);
        log.info("商品价格校验结果:{}", JSONUtil.toJsonStr(priceCheckRequest) );
    }


}

输出结果,

好了今天就到这里,有兴趣的同学可以自己试一下。

另外将 AgentPricePercentageDifferenceHandler 放到倒数第二个,是可以延迟计算。

还可以再在处理类处理了请求的时候,将处理次数加一进行统计,经过一段时间,用定时任务统计每个处理器的次数,将次数多的处理器动态调整放到前面。

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

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

相关文章

SpringBoot之Profile的两种使用方式

0. 需求 通常项目开发过程中&#xff0c;会经历多种环境转换&#xff0c;典型的如开发环境(dev)、测试环境(test)和生产环境(prod)。在这三种不同的环境下&#xff0c;连接数据库时使用的配置信息是不同的&#xff0c;即三个不同环境对应三个不同的数据库。 现在的需求是&#…

【论文导读】Graphusion (LLM + KGC)

序言 第一次论文出现在 《Leveraging Large Language Models for Concept Graph Recovery and Question Answering in NLP Education》 论文地址&#xff1a;https://arxiv.org/abs/2402.14293 七月份的时候应该是又改进了一次。但是又发了一篇新的地址&#xff1a;《Graphu…

css 中 ~ 符号、text-indent、ellipsis、ellipsis-2、text-overflow: ellipsis、::before的使用

1、~的使用直接看代码 <script setup> </script><template><div class"container"><p><a href"javascript:;">纪检委</a><a href"javascript:;">中介为</a><a href"javascript:…

SpringAOP实现的两种方式-JDK动态代理和CGLIB动态代理

前言 想要了解SpringAOP的实现方式&#xff0c;需要先了解什么是AOP OOP和AOP的区别 OOP 面向对象&#xff0c;允许开发者定义纵向的关系&#xff0c;但并适用于定义横向的关系&#xff0c;导致了大量代码的重复&#xff0c;而不利于各个模块的重用。 AOP&#xff0c;一般称为…

让小脚本成为自己高效测试的工具

测试中会遇到的工具 软件测试如果仅仅靠手工去执行会发现在很多地方力不从心&#xff0c;虽然市面上已经有大牛开源了一些测试工具可以供我们使用但是在一些公司特有的业务方面则需要我们借助开源或重新做一个自己的测试工具。 测试常用的开源工具 死链接检测工具 Xenu home…

如何使用便签高效管理自己的工作和时间?

在快节奏的现代生活中&#xff0c;我们每天都要面对众多工作任务&#xff0c;而时间却是有限的。如何在有限的时间内高效地完成工作&#xff0c;成为了每个职场人士必须面对的挑战。为了更好地管理时间&#xff0c;提高工作效率&#xff0c;我们往往需要借助一些工具来帮助我们…

Linux上Java项目环境安装

java环境 一.免费的管理Linux软件 家庭/学校免费 - NetSarang Website (xshell.com) 二.安装jdk // 检查以前是否安装过jdk java -version // 我们还可以通过以下指令来看我们安装了多少openJDK apt list --installed | grep openjdk// 如果你想卸载某个apt安装的java版本&am…

CMOS Sensor调试笔记

最近在调CMOS Sensor&#xff1b;基于无ISP的芯片。 第一步&#xff0c;找模组厂要到对应Sensor对应分辨率&#xff0c;YUV信息的驱动。 第二步&#xff0c;确认信号的极性&#xff0c;VSYNC&#xff0c;SYNC, PCLK。 第三步&#xff0c;开始测试。 问题解决&#xff1a; 1&am…

覆盖生活中各方面的5款软件,非常好用

​ 在现代生活中&#xff0c;各类工具软件为我们提供了便捷的解决方案&#xff0c;从日程管理到系统优化&#xff0c;再到文件传输与多媒体编辑&#xff0c;各类软件的功能多样&#xff0c;极大地提升了我们的工作与生活效率。 1.日历清单——日历清单 ​ 日历清单是一款集日…

运营计划管理——电商运营(案例分享)

运营计划&#xff0c;作为运营管理的重要组成部分&#xff0c;通过科学规划与有效执行&#xff0c;对确保企业目标实现起着至关重要的作用。 运营计划是指通过制定、执行、监控和调整运营计划&#xff0c;以确保企业资源得到合理配置&#xff0c;业务活动有序进行&#xff0c;最…

学习threejs,添加户外光照光源

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言二、&#x1f340;绘制任意字体模型…

windows 桌面采集音频

头文件&#xff1a; #ifndef __CAPTURE_AUDIO__ #define __CAPTURE_AUDIO__#include <functional> #include <windows.h> #pragma comment(lib, "winmm.lib")class CaptureAudio { public:CaptureAudio();~CaptureAudio();public:bool Init(const std::…

云计算Openstack Glance

OpenStack Glance&#xff08;或称为Glance&#xff0c;但通常OpenStack官方文档中使用的是“Glance”作为项目代号&#xff09;是OpenStack的镜像服务组件&#xff0c;为创建虚拟机提供镜像服务。以下是对OpenStack Glance的详细解析&#xff1a; 一、基本功能 Glance主要提…

【HTML并不简单】笔记2-你不知道的a元素属性:target、download、ping、referrerpolicy和href

文章目录 target属性download属性ping属性referrerpolicyhref细节自动绝对地址锚点定位无障碍访问为何base元素无人问津实现链接元素a的嵌套 《HTML并不简单&#xff1a;Web前端开发精进秘籍》张鑫旭 笔记 target属性 有场景如下&#xff1a; 在线写作工具经常会有预览功能&a…

源2.0-M32大模型适配AutoGPTQ工具及量化推理教程

AutoGTPQ简介 AutoGPTQ‌是一个开源工具包&#xff0c;专注于简化大规模语言模型(LLMs)的量化过程。它基于高效的GPTQ算法开发&#xff0c;主要使用Python编程语言&#xff0c;并依托PyTorch框架来实现量化功能。AutoGPTQ的设计目标是为开发者和研究人员提供一个易于使用的API接…

【Golang】关于Go语言数学计算、随机数生成模块--math

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

多功能声学气膜馆:承载梦想与希望的舞台—轻空间

在9月29日上午&#xff0c;苏州大学应用技术学院的2024级新生开学典礼暨开学第一课在轻空间建造的多功能声学气膜馆内盛大举行。这一盛典不仅见证了2849名新生的入学&#xff0c;也展示了气膜馆的独特魅力与优越功能。 卓越的声学表现 声学气膜馆采用高性能材料&#xff0c;确保…

Linux-基础实操篇-组管理和权限管理(上)

Linux 组基本介绍 在 linux 中的每个用户必须属于一个组&#xff0c;不能独立于组外。在 linux 中每个文件 有所有者、所在组、其它组的概念。 用户和组的基本概念&#xff1a; 用户名&#xff1a;用来识别用户的名称&#xff0c;可以是字母、数字组成的字符串&#xff0…

解决DHCP服务异常导致设备无法获取IP地址的方法

DHCP在网络环境中会自动为网络中的设备分配IP地址和其他关键网络参数&#xff0c;可以简化网络配置过程。但是&#xff0c;如果DHCP服务出现异常时&#xff0c;设备可能无法正常获取IP地址&#xff0c;会影响到网络通信。 本文讲述一些办法可以有效解决DHCP服务异常导致设备无法…