使用工厂方法模式实现各种不同分润规则

2024-04-05 00:48

本文主要是介绍使用工厂方法模式实现各种不同分润规则,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本人邮箱: kco1989@qq.com
欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kco
github: https://github.com/kco1989/kco
代码已经全部托管github有需要的同学自行下载

引言

在上一篇文章中使用简单工厂编写不同的分润规则遗留着一个问题,那就是如果要新增分润规则,则需要修改原来的类.也就是代码没有完全解耦.
因此在这一篇中,我将分润规则的设计改为抽象工厂模式来编写.以解决上次遗留的问题.

改写示例

分润规则接口类

该类与上一篇是一样的.

public interface ProfitRole {double getProfit(double money);
}

分润规则抽象工厂类

public abstract class ProfitRoleFactory {public static ProfitRole createProfitRole(String profitTypeName, String expression){ProfitType profitType = ProfitType.getProfitType(profitTypeName);Matcher matcher = profitType.getPattern().matcher(expression);if (!matcher.matches()){throw new RuntimeException("分润表示时不符合" + profitType.getName() + "的规则.");}return profitType.getFactory().newProfitRole(profitType, matcher, expression);}protected abstract ProfitRole newProfitRole(ProfitType profitType, Matcher matcher, String expression);}

该类主要提供一个统一的接口ProfitRoleFactory.createProfitRole创建分润规则实现类
每一个分润规则实现类对应一个分润规则工厂类,由分润规则工厂类来创建出分润规则对象
再由分润规则对象实现具体的分润细节

分润规则类型

上一篇使用到的枚举类型.但是java不支持动态增加枚举成员.所以如果这一篇还是使用枚举类型的话,则在增加新的分润规则时难免需要修改该枚举类型.
因此,这一篇不是枚举类型.

public class ProfitType {// 非捕捉匹配正实数public static final String number = "(?:(?:[1-9]+\\d*)|(?:\\d))(?:\\.\\d+)?";// 捕捉匹配正实数public static final String realNumber = "(" + number + ")";// 捕捉匹配百分比public static final String rateNumber = realNumber + "%";// 分润规则mapprivate static final Map<String, ProfitType> profitTypeMap = new HashMap<>();static {ProfitType.registerProfitRole("FIXED_RATE","^"+ ProfitType.rateNumber +"$",new FixedRateRoleFactory(),"每笔收益率为0.1%则填写代理商收益0.1%;");ProfitType.registerProfitRole("FIXED_INCOME","^" + ProfitType.realNumber + "$",new FixedIncomeRoleFactory(),"每笔固定收益1元,则填写代理商收益1.00");ProfitType.registerProfitRole("FIXED_RATE_AND_FIXED_INCOME","^"+ ProfitType.rateNumber  + "\\+" + ProfitType.realNumber + "$",new FixedRateAndFixedIncomeRoleFactory(),"每笔收益率为0.1%加上固定收益1元,则填写代理商收益0.1%+1.00");ProfitType.registerProfitRole("FIXED_RATE_AND_UPPER_LIMIT","^"+ ProfitType.realNumber + "~" + ProfitType.rateNumber + "~" + ProfitType.realNumber  + "$",new FixedRateAndUpperLimitRoleFactory(),"每笔收益率为0.1%,封顶3元,保底1元则填写代理商收益1.00~0.1%~3.00;");ProfitType.registerProfitRole("GRADIENT_RATE","^"+ ProfitType.rateNumber+"(<"+ ProfitType.realNumber+"<"+ ProfitType.rateNumber+")+$",new GradientRateRoleFactory(),"梯度分润 例如 0.1%<10000<0.2%<20000<0.3%<30000<0.5%");}private String name;private String expression;private String description;private ProfitRoleFactory factory;public ProfitType(String name, String expression, ProfitRoleFactory factory, String description) {this.name = name;this.expression = expression;this.factory = factory;this.description = description;}public static Pattern getNumberPattern() {return Pattern.compile(number);}public String getName() {return name;}public Pattern getPattern(){return Pattern.compile(this.expression);}/*** 注册分润规则类型*/public static void registerProfitRole(String name, String profitRoleExpression,ProfitRoleFactory factory, String description){if (profitTypeMap.containsKey(name)){throw new RuntimeException("该"+name+"分润规则已经存在");}profitTypeMap.put(name, new ProfitType(name, profitRoleExpression, factory, description));}public ProfitRoleFactory getFactory() {return factory;}public String getDescription() {return description;}/*** 根据分润规则名字获取分润规则类型*/public static ProfitType getProfitType(String name){return profitTypeMap.get(name);}public static String getProfitTypeInfo(){StringBuilder sb = new StringBuilder();for (Map.Entry<String, ProfitType> entry : profitTypeMap.entrySet()){sb.append(entry.getKey() + " --> " + entry.getValue().getDescription() + "\n");}return sb.toString();}
}

ProfitType.profitTypeMap 存放分润类型名称和分润类型的key-value值
ProfitType.registerProfitRole 提供一个注册分润类型的借口
ProfitType static域 默认增加上一篇提到的5种分润规则

分润规则工厂类和分润规则实现类

目前提供五种分润规则:
1. 每笔固定收益1元,则填写代理商收益1.00
2. 每笔收益率为0.1%则填写代理商收益0.1%
3. 每笔收益率为0.1%加上固定收益1元,则填写代理商收益0.1%+1.00
4. 每笔收益率为0.1%,封顶3元,保底1元则填写代理商收益1.00~0.1%~3.00
5. 梯度分润 例如 0.1%<10000<0.2%<20000<0.3%<30000<0.5%
- 少于10000 按照 0.1% 分润
- 少于20000 按照 0.2% 分润
- 少于30000 按照 0.3% 分润
- 多于30000 按照 0.5% 分润

分别对应于分润规则工厂类 -> 分润规则实现类:

  1. FixedIncomeRoleFactory -> FixedIncomeRole
  2. FixedRateRoleFactory -> FixedRateRole
  3. FixedRateAndFixedIncomeRoleFactory -> FixedRateAndFixedIncomeRole
  4. FixedRateAndUpperLimitRoleFactory -> FixedRateAndUpperLimitRole
  5. GradientRateRoleFactory -> GradientRateRole

实现新的分润规则

如果需要实现新的分润规则,则分别编写一个分润规则工厂类和分润规则实现类,使其实分别继承(/实现)ProfitRoleFactoryProfitRole,然后再调用ProfitType.registerProfitRole注册一下新的分润规则就万事大吉了.不需要修改原有的代码.也就是实现了完全解耦.

测试类

public class TestProfitRole2 {private static final List<Double> testDate = Arrays.asList(100.0,200.0,300.0,400.0,700.0,1000.0,2000.0,3000.0,7000.0,10000.0, 20000.0, 30000.0, 70000.0);@Testpublic void test(){String profitTypeInfo = ProfitType.getProfitTypeInfo();System.out.println(profitTypeInfo);}@Testpublic void testFixedIncome(){for (double data : testDate){ProfitRole fixedIncome = ProfitRoleFactory.createProfitRole("FIXED_INCOME", "1.00");double profit = fixedIncome.getProfit(data);Assert.assertEquals(1.00, profit, 0.00001);}}@Testpublic void testFixedRate(){for (double data : testDate){ProfitRole fixedRate = ProfitRoleFactory.createProfitRole("FIXED_RATE", "0.1%");double profit = fixedRate.getProfit(data);Assert.assertEquals(data * 0.1 * 0.01, profit, 0.00001);}}@Testpublic void testFixedRateAndFixedIncome(){for (double data : testDate){ProfitRole profitRole = ProfitRoleFactory.createProfitRole("FIXED_RATE_AND_FIXED_INCOME", "0.63%+3.00");double profit = profitRole.getProfit(data);Assert.assertEquals(data * 0.63 * 0.01 + 3.0, profit, 0.00001);}}@Testpublic void testFixedRateAndUpperLimit(){for (double data : testDate){ProfitRole profitRole = ProfitRoleFactory.createProfitRole("FIXED_RATE_AND_UPPER_LIMIT", "1.00~0.1%~3.00");double profit = profitRole.getProfit(data);double actual = data * 0.1 * 0.01;if (actual < 1.0){actual = 1.0;}if (actual > 3.0){actual = 3.0;}Assert.assertEquals(actual, profit, 0.00001);}}@Testpublic void testGradientRate(){for (double data : testDate){ProfitRole profitRole = ProfitRoleFactory.createProfitRole("GRADIENT_RATE", "0.1%<1000<0.2%<5000<0.3%<15000<0.5%");double profit = profitRole.getProfit(data);if (data < 1000){Assert.assertEquals(data * 0.01 * 0.1, profit, 0.00001);}else if (data < 5000){Assert.assertEquals(data * 0.01 * 0.2, profit, 0.00001);}else if(data < 15000){Assert.assertEquals(data * 0.01 * 0.3, profit, 0.00001);}else{Assert.assertEquals(data * 0.01 * 0.5, profit, 0.00001);}}}
}

打赏

如果觉得我的文章写的还过得去的话,有钱就捧个钱场,没钱给我捧个人场(帮我点赞或推荐一下)
微信打赏支付宝打赏

这篇关于使用工厂方法模式实现各种不同分润规则的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/877246

相关文章

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

nginx启动命令和默认配置文件的使用

《nginx启动命令和默认配置文件的使用》:本文主要介绍nginx启动命令和默认配置文件的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录常见命令nginx.conf配置文件location匹配规则图片服务器总结常见命令# 默认配置文件启动./nginx

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

PostgreSQL中MVCC 机制的实现

《PostgreSQL中MVCC机制的实现》本文主要介绍了PostgreSQL中MVCC机制的实现,通过多版本数据存储、快照隔离和事务ID管理实现高并发读写,具有一定的参考价值,感兴趣的可以了解一下... 目录一 MVCC 基本原理python1.1 MVCC 核心概念1.2 与传统锁机制对比二 Postg

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4