真实业务场景使用-门面模式(外观)设计模式
1.前言
最近接到要修改的业务功能,这个业务增删改查很多功能都需要校验时间,比如:
1.失效时间不能超过自己父表的失效时间,
2.失效时间不能是当前时间
3.失效时间不能早于生效时间
类似这样的不同的判断还有很多,我就先举这三种例子,因为这是在一个管理功能,也许未来还有很多的这样的规则处理,所以需要好好的设计下。
2.设计实现
我想着对于这种校验是一种规则,而对于时间的校验就是时间校验规则,所以我们定义个接口,某某业务时间规则接口,并定义了两个方法,一个是对传过来的两个时间的校验范围,一个是对当前时间及另一个传输过来的时间校验范围,如下伪代码
public interface XxBussinessDateRule{/**传入两个时间进行校验*/boolean dateScopeValidate(String dateOne,String dateTwo,MathSymbolsEnum mathSymbols);/**传入时间与当前时间进行校验*/boolean dateScopeValidateByCurrent(String date,MathSymbolsEnum mathSymbols);
}
MathSymbolsEnum枚舉類是专门处理数学符号的,如大于(>),小于(<),小于等于(<=)等等等等,
传输这个值才能更灵活处理校验规则。
public enum MathSymbolsEnum{/**大于*/GREATER_THAN,/**小于*/LESS_THAN,/**小于等于*/EQUAL_OR_LESS_THAN,/**大于等于*/EQUAL_OR_GREATER_THAN,/**等于*/EQUAL,/**不等于*/NOT_EQUAL,
}
DefaultxxBussinessRule类:是xxBussinessRule的实现类,因为只有此一个实现类,所以名称里加一个Default,这个类主要是对时间的校验,需要根据枚举类的符号进行判断,如果大于就调用此类私有方法dateValidateGreaterThan,如果小于就找私有方法dateValidateLessThan,用于处理不同情况的校验。
在我原有的实现里,这里调用的是不同工具类的处理方法。伪代码呢就直接写死true,False返回,你可随意实现
@Component
public class DefaultxxBussinessDateRule implements XxBussinessDateRule {/*** 传入两个时间进行校验*/@Overridepublic boolean dateScopeValidate(String dateOne, String dateTwo, MathSymbolsEnum mathSymbols) {// 大于if (mathSymbols.name().equals("GREATER_THAN")) {return dateValidateGreaterThan(dateOne, dateTwo);}// 小于if (mathSymbols.name().equals("LESS_THAN")) {return dateValidateLessThan(dateOne, dateTwo);}return false;}/*** 传入时间与当前时间进行校验*/@Overridepublic boolean dateScopeValidateByCurrent(String date, MathSymbolsEnum mathSymbols) {// 小于等于if (mathSymbols.name().equals("EQUAL_OR_LESS_THAN")) {System.out.println("模拟校验:是否小于等于");return true;}return false;}private boolean dateValidateGreaterThan(String dateOne, String dateTwo) {// 模拟校验规则// 假如第一个时间大于第二个时间System.out.println("模拟校验:是否大于");return true;}private boolean dateValidateLessThan(String dateOne, String dateTwo) {// 模拟校验规则// 假如第一个时间小于第二个时间System.out.println("模拟校验:是否小于");return true;}}
正常到这里就结束了,但是又考虑了下,未来如果这个功能又要加其他规则呢,和本次时间规则毫无关系呢,那就又需要新建接口,定义新的方法,ok没有问题,问题是如果再继续新加接口、定义方法呢,有这么多类都是这个功能下的规则,入口却是多个,业务逻辑也许并不相通,怎么办?
所以,加个类,这个类用来封装统一调用不同的入口使用,这个想法思路也叫门面模式(外观模式)。
门面模式:不想让用户调用更繁杂的方法,也不用让用户了解内部具体的实现,只要简单一调用就可实现方法即可。
新建统一门面类:XxBussnissRule,继承了基础的校验规则类(下面有讲),依赖业务时间类,并定义实现两个方法,这两个方法调用到了时间校验类里的规则,这样所有的调用方都以这个为入口,都调用到这里
@Component
public class XxBussnissRule extends BaseValidateRule{@Resourcce private XxBussinessDateRule xxBussinessDateRule;public boolean dateScopeValidate(String dateOne,String dateTwo,MathSymbolsEnum mathSymbols){return xxBussinessDateRule.dateScopeValidate(dateOne,dateTwo,mathSymbols);}public boolean dateScopeValidateByCurrent(String date,MathSymbolsEnum mathSymbols){return xxBussinessDateRule.dateScopeValidateByCurrent(date,mathSymbols);}}
加了这个统一的入口,调用就很方便了,未来添加别的规则,只要在这个类里添加即可。
除了这一点以外,我们可能会有些通用规则,对于入参可能会有判空、校验入参字段长度啊等等一些基础规则,那么我们需要新建类:BaseValidateRule
这样,XxBussnissRule就可以继承BaseValidateRule类,用户调用XxBussnissRule就自然有了基础规则的功能。
public class BaseValidateRule{// 举例...public boolean isLength(){return true;}
}
3.测试准备
测试使用,单元测试调用业务规则校验时间伪代码,可以看到,我们使用统一的类调用即可,外部引用则可以直接引用这一个类,未来扩展其他规则,还可以依赖这个入口。
@SpringBootTest
public class TestApi {@Resourceprivate XxBussnissRule xxBussnissRule;@Testpublic void testFaced() {boolean dateValidate = xxBussnissRule.dateScopeValidate("2023-05-02", "20233-05-04", MathSymbolsEnum.GREATER_THAN);boolean dateValidateByCurrent = xxBussnissRule.dateScopeValidateByCurrent("2023-05-17", MathSymbolsEnum.LESS_THAN);System.out.println("两个日期校验比对模拟:"+dateValidate);System.out.println("与当前日期校验比对模拟:"+dateValidateByCurrent);}
}
执行结果,证明流程走下來了。

相关文章:
真实业务场景使用-门面模式(外观)设计模式
1.前言 最近接到要修改的业务功能,这个业务增删改查很多功能都需要校验时间,比如: 1.失效时间不能超过自己父表的失效时间, 2.失效时间不能是当前时间 3.失效时间不能早于生效时间 类似这样的不同的判断还有很多,…...
基于多动作深度强化学习的柔性车间调度研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
出口亚马逊平衡车CE/UKCA认证注意事项
平衡车UKC认证 CE认证 认证项目:BS EN/EN71-1-2-3 UKCA认证标志与CE认证标志有什么不同? UKCA标记过程基本上遵循与CE标记相同的规则和规定。大多数制造商仍然可以根据测试结果和其他技术文档自行声明他们的产品,但在特定情况下,他们需要从第…...
云原生环境下的安全实践:保护应用程序和数据的关键策略
文章目录 云原生环境下的安全实践:保护应用程序和数据的关键策略一.安全措施和实践1. 身份和访问管理:2. 容器安全:3. 网络安全:4. 日志和监控:5. 持续集成和持续交付(CI/CD)安全:6.…...
vue 改变数据后,数据变化页面不刷新
文章目录 导文文章重点方法一:使用this.$forceUpdate()强制刷新方法二:Vue.set(object, key, value)方法三:this.$nextTick方法四:$set方法 导文 在vue项目中,会遇到修改完数据,但是视图却没有更新的情况 v…...
【Qt编程之Widgets模块】-006:QSortFilterProxyModel代理的使用方法
QSortFilterProxyModel是model的代理,不能单独使用,真正的数据需要另外的一个model提供,它的工鞥呢是对被代理的model(source model)进行排序和过滤。所谓过滤:也就是说按着你输入的内容进行数据的筛选,因为器过滤功能…...
上林赋 汉 司马相如
亡是公听然而笑曰:“楚则失矣,而齐亦未为得也。夫使诸侯纳贡者,非为财币,所以述职也。封疆画界者,非为守御,所以禁淫也。今齐列为东藩,而外私肃慎,捐国逾限,越海而田&…...
7.对象模型
对象模型 信号和槽 信号和槽是一种用于对象之间通信的机制。信号是对象发出的通知,槽是用于接收这些通知的函数。 当对象的状态发生变化时[按钮被点击],它会发出一个信号[clicked()],然后与该对象连接的槽函数将被自动调用。 若某个信号与多…...
机器学习——基本概念
如何选择合适的模型评估指标?AUC、精准度、召回率、F1值都是什么?如何计算?有什么优缺点? 选择合适的模型评估指标需要结合具体的问题场景,根据不同的需求来选择不同的指标。以下是几个常用的评估指标: AUC…...
Qt---感觉挺重要的部分
目录 一、讲述Qt信号槽机制与优势与不足 二、Qt信号和槽的本质是什么 三、描述QT中的文件流(QTextStream)和数据流(QDataStream)的区别 四、描述QT的TCP通讯流程 服务端:(QTcpServer) 客户端:(QTcpSocket…...
springboot+vue家乡特色推荐系统(源码+文档)
风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的家乡特色推荐系统。项目源码以及部署相关请联系风歌,文末附上联系信息 。 💕💕作者:风…...
在Shell脚本中通过ssh从脚本运行函数
文章目录 在Shell脚本中通过ssh从脚本运行函数declare -f 和typset -f,这两个命令有什么区别declare -f 和typset -f,这两个命令可以通过ssh运行脚本中的函数吗如果我有main.sh和util.sh,并且在main.sh中引用了util.sh,该怎么办&a…...
简单学习一下 MyBatis 动态SQL使用及原理
MyBatis 是一个优秀的持久层框架,它提供了丰富的 SQL 映射功能,可以让我们通过 XML 或注解方式来定义 SQL 语句。它很大程度上简化了数据库操作,提高了开发效率。动态 SQL 是其中一个非常重要的功能,可以让我们根据不同的条件动态…...
WhatsApp如何让客户参与变得更简单?
WhatsApp对你的品牌来说可能和Twitter和Facebook一样重要,你可能已经把它们纳入你的社交媒体战略。 是的,WhatsApp不仅仅可以用来给同事发短信或与远方的亲戚视频聊天,它也适用于商业。 在发展WhatsApp业务时,小企业主得到了最优…...
记一次 MySQL 主从同步异常的排查记录,百转千回
本文主要内容如下: 一、现象 最近项目的测试环境遇到一个主备同步的问题: 备库的同步线程停止了,无法同步主库的数据更改。 备库报错如下: 完整的错误信息: Relay log read failure: Could not parse relay log even…...
Cpython的多线程技术之痛
历史原因 在Python官网下载的默认解释器是采用C语言编写的Cpython解释器。在Python语言开发之初,计算机都是单核CPU,每个单核CPU同一时刻只能运行一个线程。为了模拟多线程工作,这里采用了模拟机制,让不同线程根据时间片段&#…...
NDK OpenGL离屏渲染与工程代码整合
NDK系列之OpenGL离屏渲染与工程代码整合,本节主要是对上一节OpenGL渲染画面效果代码进行封装设计,将各种特效代码进行分离解耦,便于后期增加其他特效。 实现效果: 实现逻辑: 1.封装BaseFilter过滤器基类,…...
Python基础入门编程代码练习(二)
一、求1~100之间不能被3整除的数之和 循环条件:i<100循环操作 实现代码如下: def sums():sum 0for num in range(1, 101):if num % 3 ! 0:sum numprint("1~100之间不能被3整除的数之和为:%s" % (sum))sums() print("1~…...
C# | 对象池
对象池 文章目录 对象池前言什么是对象池对象池的优点对象池的缺点 实现思路示例代码 结束语 前言 当我们开发一个系统或者应用程序时,我们通常需要创建很多的对象,这些对象可能是线程、内存、数据库连接、文件句柄等等。在某些情况下,我们需…...
CSS小技巧之圆形虚线边框
虚线相信大家日常都用的比较多,常见的用法就是使用 border-style 控制不同的样式,比如设置如下边框代码: border-style: dotted dashed solid double;这将设置顶部的边框样式为点状,右边的边框样式为虚线,底部的边框样…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
