以下内容带大家一起设计一个验证功能模块,既然要做一个这样的模块,我们就把有关的概念做一下设计。
验证器
package cc.soft.validate; import cc.soft.validate.ValidateException; public interface Validator { void validate(Object obj) throws ValidateException; }
验证异常类
package cc.soft.validate; @SuppressWarnings("serial") public class ValidateException extends Exception { public ValidateException() { // TODO Auto-generated constructor stub } public ValidateException(String message) { super(message); // TODO Auto-generated constructor stub } public ValidateException(Throwable cause) { super(cause); // TODO Auto-generated constructor stub } public ValidateException(String message, Throwable cause) { super(message, cause); // TODO Auto-generated constructor stub } public ValidateException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { super(message, cause, enableSuppression, writableStackTrace); // TODO Auto-generated constructor stub } }
验证结果
package cc.soft.validate; public class Violation { private String path; private String message; public String getPath() { return path; } public void setPath(String path) { this.path = path; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } @Override public String toString() { return "Violation [path=" + path + ", message=" + message + "]"; } }
验证规则
package cc.soft.validate; public interface ValidateRule extends ValidateNode { }
验证节点
package cc.soft.validate; import java.util.List; public interface ValidateNode { List<ValidateNode> getChildren(); void setChildren(List<ValidateNode> children); Validator[] getValidators(); void setValidators(Validator[] validators); }
验证上下文
package cc.soft.validate; import java.util.List; public interface ValidateContext { List<Violation> validate(Object target, ValidateRule rule) throws Exception; }
以上的其它模型概念都比较好理解,这里说一下ValidateNode是如何抽象出来的,假如有两个类型如下
package cc.soft.validate; public class Book { /** * 书名 */ private String name; /** * 作者 */ private Person author; public String getName() { return name; } public void setName(String name) { this.name = name; } public Person getAuthor() { return author; } public void setAuthor(Person author) { this.author = author; } }
package cc.soft.validate; public class Person { /** * 姓名 */ private String name; /** * 别名 */ private String[] alisNames; public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getAlisNames() { return alisNames; } public void setAlisNames(String[] alisNames) { this.alisNames = alisNames; } }
现有一个Book实例 book, book.getName() 可以用来描述书本名这个值,book.getOwner().getName() 可以用来描述书本作者的名字的值, book.getOwner().getAlisNames()[0] 可以用来描述书本作者的第一个别名,另外我们也可以使用另外一种,
根值(RootBean) + 路径(Path)的方式。想必用过Xpath的朋友都很熟悉了。
书本名=book + /name
作者名=book + /onwer/name
第一个别名值 = book + /owner/alisNames/1 (为什么不写成 /owner/alisNames[0], 咱就别纠结这了…… 嘿嘿,别忘了我们的目标是来讨论ValidateNode是怎么来的)
我们把路径用/切分, 是不是就切成了一节一节的, 这么一节一节的就是我们的那个ValidateNode了。藕断丝连,那么Node就是一个链式结构(先别怼我看到的Node结构不是一个链式结构),每一个Node都有0或1个上级Node, 但因为有的Node是共用的,自然就把他设计成树结构比较好点吧,这样一来,从叶子往根看,还是一条链。好了 ValidateNode#getChildren(); 这个事情算说明白了。
再看 ValidateNode#getValidators()是怎么回事。从Validator这个类角度来看,他的功能就是验证一个给定的Object值,如果不符合规则,就抛出一个ValidateException,至于规则嘛,就是模块的扩展点了,这个就符合了Validator接口的设计。 从要验证的Object值角度来看,一个值有1个或多个Validator。所以ValidateNode#getValidators()就说通了。
ValidateRule 呢,咱就认为是一个树根的 ValidateNode就行了。
这么一下来可以这么描述
/name [{验证器1},{验证器2}……]
/onwer/name [{验证器4},{验证器4}……]
/owner/alisNames/* [{验证器5},{验证器6}……]
再回头看看我们的路径描述 如 /owner/alisNames/1 切断了之后, 应该有两种类型的Node, 一种是有名称的,一种是代表集合的。因此设计如下两个类型
package cc.soft.validate.core; public class SimpleValidateNode extends AbstractValidateNode { private String name; public SimpleValidateNode(String name) { super(); this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package cc.soft.validate.core; public class ArrayValidateNode extends AbstractValidateNode { }
好了,概念模型大概梳理已经完成,接下来就是实现这套模型了。实现的过程没什么好解释的,有兴趣的可以把代码下载来参考
在这里引入一个题外话,只有核心没有外围的东西,不好用。 我们知道一杆Q的核心 Q樘+Z弹+Z针, 但你见过一把Q只包含这三样的么, 都是为了各种需求,加上D夹呀,准镜呀 才是一个实用的Q。回到话题,规则如何定义?
在 bean上用Annotation来定义?
用 path=[验证器集合描述] 的kv方式?
还是其它的方式,外围不可轻视,决定着你的产品的易用性
以下是使用json来定义的规则,*代表的是多值字段 &代表的是子属性类型的规则定义
{ "name": [ { "type": "required", "message": "书名必填" }, { "type": "length", "minLength": "3", "message": "书名长度不小于3" } ], "author": [ { "type": "required", "message": "书名作者必填" } ], "author&": { "name": [ { "type": "required", "message": "姓名必填" } ], "alisNames": [ { "type": "required", "message": "别名必填" } ], "alisNames*": [ { "type": "required", "message": "值必填" }, { "type": "length", "minLength": "3", "message": "别名长度不小于3" } ] } }
好了,第一次写文章,到此为止。
相关推荐
嵌入式八股文面试题库资料知识宝典-华为的面试试题.zip
训练导控系统设计.pdf
嵌入式八股文面试题库资料知识宝典-网络编程.zip
人脸转正GAN模型的高效压缩.pdf
少儿编程scratch项目源代码文件案例素材-几何冲刺 转瞬即逝.zip
少儿编程scratch项目源代码文件案例素材-鸡蛋.zip
嵌入式系统_USB设备枚举与HID通信_CH559单片机USB主机键盘鼠标复合设备控制_基于CH559单片机的USB主机模式设备枚举与键盘鼠标数据收发系统支持复合设备识别与HID
嵌入式八股文面试题库资料知识宝典-linux常见面试题.zip
面向智慧工地的压力机在线数据的预警应用开发.pdf
基于Unity3D的鱼类运动行为可视化研究.pdf
少儿编程scratch项目源代码文件案例素材-霍格沃茨魔法学校.zip
少儿编程scratch项目源代码文件案例素材-金币冲刺.zip
内容概要:本文深入探讨了HarmonyOS编译构建子系统的作用及其技术细节。作为鸿蒙操作系统背后的关键技术之一,编译构建子系统通过GN和Ninja工具实现了高效的源代码到机器代码的转换,确保了系统的稳定性和性能优化。该系统不仅支持多系统版本构建、芯片厂商定制,还具备强大的调试与维护能力。其高效编译速度、灵活性和可扩展性使其在华为设备和其他智能终端中发挥了重要作用。文章还比较了HarmonyOS编译构建子系统与安卓和iOS编译系统的异同,并展望了其未来的发展趋势和技术演进方向。; 适合人群:对操作系统底层技术感兴趣的开发者、工程师和技术爱好者。; 使用场景及目标:①了解HarmonyOS编译构建子系统的基本概念和工作原理;②掌握其在不同设备上的应用和优化策略;③对比HarmonyOS与安卓、iOS编译系统的差异;④探索其未来发展方向和技术演进路径。; 其他说明:本文详细介绍了HarmonyOS编译构建子系统的架构设计、核心功能和实际应用案例,强调了其在万物互联时代的重要性和潜力。阅读时建议重点关注编译构建子系统的独特优势及其对鸿蒙生态系统的深远影响。
嵌入式八股文面试题库资料知识宝典-奇虎360 2015校园招聘C++研发工程师笔试题.zip
嵌入式八股文面试题库资料知识宝典-腾讯2014校园招聘C语言笔试题(附答案).zip
双种群变异策略改进RWCE算法优化换热网络.pdf
内容概要:本文详细介绍了基于瞬时无功功率理论的三电平有源电力滤波器(APF)仿真研究。主要内容涵盖并联型APF的工作原理、三相三电平NPC结构、谐波检测方法(ipiq)、双闭环控制策略(电压外环+电流内环PI控制)以及SVPWM矢量调制技术。仿真结果显示,在APF投入前后,电网电流THD从21.9%降至3.77%,显著提高了电能质量。 适用人群:从事电力系统研究、电力电子技术开发的专业人士,尤其是对有源电力滤波器及其仿真感兴趣的工程师和技术人员。 使用场景及目标:适用于需要解决电力系统中谐波污染和无功补偿问题的研究项目。目标是通过仿真验证APF的有效性和可行性,优化电力系统的电能质量。 其他说明:文中提到的仿真模型涉及多个关键模块,如三相交流电压模块、非线性负载、信号采集模块、LC滤波器模块等,这些模块的设计和协同工作对于实现良好的谐波抑制和无功补偿至关重要。
内容概要:本文探讨了在工业自动化和物联网交汇背景下,构建OPC DA转MQTT网关软件的需求及其具体实现方法。文中详细介绍了如何利用Python编程语言及相关库(如OpenOPC用于读取OPC DA数据,paho-mqtt用于MQTT消息传递),完成从OPC DA数据解析、格式转换到最终通过MQTT协议发布数据的关键步骤。此外,还讨论了针对不良网络环境下数据传输优化措施以及后续测试验证过程。 适合人群:从事工业自动化系统集成、物联网项目开发的技术人员,特别是那些希望提升跨协议数据交换能力的专业人士。 使用场景及目标:适用于需要在不同通信协议间建立高效稳定的数据通道的应用场合,比如制造业生产线监控、远程设备管理等。主要目的是克服传统有线网络限制,实现在不稳定无线网络条件下仍能保持良好性能的数据传输。 其他说明:文中提供了具体的代码片段帮助理解整个流程,并强调了实际部署过程中可能遇到的问题及解决方案。
基于C#实现的检测小说章节的重复、缺失、广告等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于C#实现的检测小说章节的重复、缺失、广告等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于C#实现的检测小说章节的重复、缺失、广告等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于C#实现的检测小说章节的重复、缺失、广告等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于C#实现的检测小说章节的重复、缺失、广告等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于C#实现的检测小说章节的重复、缺失、广告等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档
少儿编程scratch项目源代码文件案例素材-火柴人终极之战.zip