用责任链模式改造 if else

news/2024/10/4 12:07:34/

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

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

java">        //代理价>销售价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 

java">/*** @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;}
}

结果枚举类

java">@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 属性是执行 下一个处理器
java">@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
java">public class AgentPriceGreaterThanGoodsPriceHandler extends PriceCheckHandler {@Overridepublic void handle(PriceCheckRequest request) {if (BigDecimalUtil.isGreaterThan(request.getAgentPrice(),request.getGoodsPrice())) {request.setPriceCheckEnum(PriceCheckEnum.AGENT_PRICE_GREATER_THAN_SALE_PRICE);}check(request);}
}

供货价大于代理价处理器

SupplyPriceGreaterThanAgentPriceHandler
java">public class SupplyPriceGreaterThanAgentPriceHandler extends PriceCheckHandler {@Overridepublic void handle(PriceCheckRequest request) {if (BigDecimalUtil.isGreaterThan( request.getSupplyPrice(), request.getAgentPrice())) {request.setPriceCheckEnum(PriceCheckEnum.SUPPLIER_PRICE_GREATER_THAN_AGENT_PRICE);}check(request);}
}
(销售价-代理价)/代理价<5% 处理器
AgentPricePercentageDifferenceHandler
java">public class AgentPricePercentageDifferenceHandler extends PriceCheckHandler {@Overridepublic 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 默认返回价格检查通过,需要把它放在责任链的最后处理器
java">public class DefaultPriceHandler extends PriceCheckHandler {@Overridepublic void handle(PriceCheckRequest request) {request.setPriceCheckEnum(PriceCheckEnum.DEFAULT);}
}

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

ChainBuilder
java">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);}}
}

最后测试

java">
@Slf4j
public class ChainBuilderTest {@Testpublic 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_PRICEpriceCheckRequest = 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_PRICEpriceCheckRequest = 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"));//DEFAULTpriceCheckRequest = new PriceCheckRequest(product);ChainBuilder.chainBuilder.process(priceCheckRequest);log.info("商品价格校验结果:{}", JSONUtil.toJsonStr(priceCheckRequest) );}}

输出结果,

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

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

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


http://www.ppmy.cn/news/1534401.html

相关文章

第九章---for循环及在STL的应用(vector\map\set\list\for_each)、嵌套while、while 统一输出、do-while

在C中&#xff0c;循环语句用于重复执行一段代码&#xff0c;直到指定的条件不再满足。C 提供了几种循环机制&#xff0c;下面将详细讲解每种循环语句的用法和特点。 1. for 循环 for 循环是最常用的循环结构之一&#xff0c;它有三种基本形式&#xff1a; 基本形式&#xf…

electron教程(三)窗口设置

在main.js文件中&#xff0c;创建窗口时会设置窗口的大小&#xff0c;其实还有很多其他属性&#xff0c;可以根据实际需求选择设置&#xff0c;但部分属性存在局限性&#xff0c;官网也有明确告知&#xff1a;自定义窗口 | Electron (electronjs.org) 项目文件目录如下&#x…

【GPT】对低阶版本的GPT探测:文学

诗名字一致&#xff0c;GPT就分不清了&#xff0c;还要多喂喂书&#xff0c;之前部分技术类的协议解析可以直接扔整本书给他自我学习。 温庭筠 相见欢 ChatGPT 说&#xff1a; ChatGPT 《相见欢》是温庭筠的一首经典词作&#xff0c;以其细腻的情感和优美的意象而著称。以下是…

[网络]NAT、代理服务、内网穿透、内网打洞

目录 一、NAT 1.1 NAT 技术背景 1.2 NAT IP 转换过程 1.3 NAPT&#xff08;Network Address Port Translation&#xff09; 1.地址转换表 2. NAPT&#xff08;网络地址端口转换Network Address Port Translation&#xff09; 3. NAT技术的缺陷 二、代理服务器 2.1 正向…

相机的内参 外参

相机的内参和外参是计算机视觉和摄影测量中的重要概念。以下是对它们的详细说明&#xff1a; 内参&#xff08;Intrinsic Parameters&#xff09; 内参定义了相机的内部特性&#xff0c;主要包括焦距、主点坐标以及畸变系数。内参矩阵 K 形式如下&#xff1a; 外参&#xf…

高级java每日一道面试题-2024年9月30日-服务器篇[Redis篇]-Redis持久化有几种方式?

如果有遗漏,评论区告诉我进行补充 面试官: Redis持久化有几种方式? 我回答: Redis 是一个高性能的键值存储系统&#xff0c;常用于缓存、消息队列和实时数据分析等场景。为了保证数据的持久性&#xff0c;Redis 提供了两种主要的持久化方式&#xff1a;RDB&#xff08;Redi…

构建高效服装销售平台:Spring Boot与“衣依”案例

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

数造科技入选中国信通院《高质量数字化转型产品及服务全景图》三大板块

9月24日&#xff0c;2024大模型数字生态发展大会暨“铸基计划”年中会议在北京召开。会上&#xff0c;中国信通院发布了2024年《高质量数字化转型产品及服务全景图&#xff08;上半年度&#xff09;》和《高质量数字化转型技术解决方案&#xff08;上半年度&#xff09;》等多项…