发生了什么事
在一次苦B程序员和苦C程序员的结对编程中发生的一段对话
代码是这样的:
public void deleteAllExtendAclsFromContent(String contentId) throws ContentAclServiceException {
// 参数验证
if (StringUtils.isBlank(contentId)) {
logger.warn("参数异常,内容唯一标识为空");
throw new ContentAclServiceException("参数异常,内容唯一标识为空");
}
// 检查内容合法性
contentAclService.checkContentId(contentId);
contentAclCoreService.deleteAllExtendAclsFromContent(contentId);
}
苦C程序员:会什么你的每个方法都要去检查一下参数是不是null,参数是不是指定的几种可选数据?
苦B程序员:因为如果我不检查,后面的操作将会是对一个错误的对象进行,会影响程序的正确执行。
苦C程序员:但是这个方法应该只关注自己的业务逻辑而不应该做一些与业务无关的参数的正确性判断,否则这个方法可能10行中有7行都是做参数合法性验证,真正的业务可能只有3行,你不觉得这会很怪异吗?
苦B程序员:那我有什么办法,我的程序跑不下去了,测试来找我的麻烦了!
苦C程序员:我看你的每个方法都要对参数做合法性检查,那是否可以将这样一个行为提取出来使所有的方法在被调用之前让一个类去做参数的合法性检查,我们只要给参数一个说明比如这样
public void deleteAllExtendAclsFromContent(@NotEmpty(message="参数异常,内容唯一标识为空") String contentId) throws ContentAclServiceException {
// 检查内容合法性
contentAclService.checkContentId(contentId);
contentAclCoreService.deleteAllExtendAclsFromContent(contentId);
}
苦B程序员:嗯,这样看起来很不错,我们可以利用spring的aop做个拦截,在所有的方法被调用前先让一个拦截器来检查所有的参数是否合法。
苦C程序员:对,我们就这样干。
没多久时序图片就出来了。
.
.
.
半天后,两个人只有一个想法,那就是太苦B了,这是一整个体系两个人一天怎么做的完?在项目的时间进度压力下两人只有放弃(看来很多情况下不是程序员不想把事情做好,时间、时间、还是时间),于是程序又回到了刚开始,并且他们不得不为这一次冒险所耽搁的时间去自己加班完成工作。
这样的事情发生的多了大家就再也不会想在项目里使用什么优美的方式或好的模式来编写与设计代码了,而是以完成功能为目地的编码。
回顾上面的对话我们发现
Ø 苦B程序员的做法,是为了防止程序出现异常而对输入参数为了检查。
Ø 苦C程序员的想法,是让这种检查工作不必分散到各业务方法中。
两个程序员都是想把程序做的更健壮、业务更清晰、职责更分明,但是由于客观的原因他们的努力失败了。
神的出现
继续上面,此时的苦C程序员依然没有放弃,他利用项目的空闲时间继续研究,他认为这种需求应该不只他一个人有,世界上还有那么多的苦X程序员,可能早就有人想到了这个需求,也许早就有人已经完成了这个工作,苦C程序员突然想起了spring的mvc中好像可以验证参数的正确性,于是他求助了万能的google大神,终于被他找了解决这个问题的究极方案。
当当当“JSR303”闪亮登场。http://jcp.org/en/jsr/detail?id=303
这个规范当前较好的实现是Hibernate Validator,http://www.hibernate.org/subprojects/validator.html并且也可较方便的与spring集成。此时的苦C程序员感觉到浑身充满了力量,他大叫一声“JSR303赐予我力量吧!Google,live for ever”。从此苦C程序员在开发这条苦B的不归路上走的更坚实了,因为他又多了一把称手的神器—“JSR303”。
苦B程序员和苦C程序员皈依了我神最终升华为苦A程序员
网上有这样一个例子https://github.com/ghillert/spring-hibernate-validator-sample,这里面就是讲述如何使用JSR303来验证方法参数的。这里面需要在spring中做如下配置
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor" />
关键就在MethodValidationPostProcessor这个类,它的作用就是给所有的标记了要做验证的接口添加一个org.springframework.validation.beanvalidation.MethodValidationInterceptor拦截器,这个拦截器会负责验证你所要验证的参数。
但这个拦截器会抛出一个org.hibernate.validator.method.MethodConstraintViolationException.MethodConstraintViolationException异常,对于有些人来说也许他们并不希望得到这样的异常,可能是因为这个异常长的太怪异,也可能是其它的原因,总之就是不希望用这个,他们希望自已来控制验证出错后的处理方式。谢天谢地这一切都是开源的(感谢天,感谢地,感谢Spring……熟悉的旋律出现在耳边),那么分析MethodValidationPostProcessor与MethodValidationInterceptor代码后我们可以很容易的做到这一点,聪明的程序员们应该很快就可以明白了。
苦C程序员以最快的速度将这个消息告诉了苦B程序员,苦B程序员得到这个消息后第一直觉就是要尽快将这个成果分享到整个团队中,于是不久后整个团队的成员都皈依了我神(JSR303)最终升华为了苦A程序员(为什么还是苦A程序员?因为还有新的麻烦会不断的出现,我勒个去……)。
分享到:
相关推荐
本书作者介绍了一些有用但很少被讨论的算法,它们可用于语音查找、日期和时间例程(直到公元1年)、B树和索引文件、数据压缩、任意精度的算术、校验和与数据验证,并且还最全面地介绍了查找例程、排序算法和数据结构...
本书(程序员常用算法)重点关注的是实用,立即可用的代码,并且广泛...日期和时间例程(直到公元1年)、B树和索引文件、数据压缩、任意精度的算术,校验和与数据验证,并且全面地介绍了查找例程、排序算法和数据结构。..
日期和时间例程(直到公元1年)、B树和索引文件、数据压缩、任意精度的算术,校验和与数据验证,并且全面地介绍了查找例程、排序算法和数据结构。.. 本书只要求读者具有C语言的初级知识以及基本代数的相关知识。源代码...
译者序 前言 ...第10章 数据完整性和验证 10.1 简单的校验和 10.2 加权校验和 10.3 循环冗余校验 10.3.1 CRC CCITT 10.3.2 CRC 16 10.3.3 CRC 32 10.4 资源和参考资料
《程序员实用算法》重点关注的是实用,立即可用的代码,并且广泛讨论...日期和时间例程(直到公元1年)、B树和索引文件、数据压缩、任意精度的算术,校验和与数据验证,并且全面地介绍了查找例程、排序算法和数据结构。
日期和时间例程(直到公元1年)、B树和索引文件、数据压缩、任意精度的算术,校验和与数据验证,并且全面地介绍了查找例程、排序算法和数据结构。.. 本书只要求读者具有C语言的初级知识以及基本代数的相关知识。源代码...
日期和时间例程(直到公元1年)、B树和索引文件、数据压缩、任意精度的算术,校验和与数据验证,并且全面地介绍了查找例程、排序算法和数据结构。.. 本书只要求读者具有C语言的初级知识以及基本代数的相关知识。源代码...
日期和时间例程(直到公元1年)、B树和索引文件、数据压缩、任意精度的算术,校验和与数据验证,并且全面地介绍了查找例程、排序算法和数据结构。.. 本书只要求读者具有C语言的初级知识以及基本代数的相关知识。源代码...
日期和时间例程(直到公元1年)、B树和索引文件、数据压缩、任意精度的算术,校验和与数据验证,并且全面地介绍了查找例程、排序算法和数据结构。.. 本书只要求读者具有C语言的初级知识以及基本代数的相关知识。源代码...
验证测试 D).验收测试 5.数据存储和数据流都是(D),仅仅是所处的状态不同。 A).分析结果 B).事件 C).动作 D).数据 6。数据流图和(C)共同组成系统的逻辑模型。 A).HIPO图 B).PD)L C).数据字典 D).层次图 7。数据元素...
通过这一章的学习,我们可能感觉到XML似乎更偏向数据处理,更方便程序员学习。实际情况也是这样的,XML设计的目的就是用来方便的共享和交互数据的。下一章,我们将系统的了解关于XML的各种术语。 二.DTD的有关...
|加州大学伯克利分校发布的 BDD100K 数据集,该数据集为迄今规模最大、最多样的自动驾驶数据集之一。 训练集数量:70000 验证集数量:20000 测试集数量:10000 类别信息 id class_name train set nums 1 pedestrian...
每个应答器 (组) 命名应以 B 开头,后加公里标或信号机名称,其中公里标参照区间通过信号机命名规则执行,即应答器名称以该应答器 (组) 所在位置坐标公里数和百米数组成,对于 km 后的单位采用四舍五入的方式计算,...
B) 数据流条目、数据项条目、文件条目、加工条目 C) 数据源条目、数据流条目、数据处理条目、数据文件条目 D) 数据流条目、数据文件条目、数据池条目、加工条目 9. 在需求分析阶段主要采用图形工具来描述的原因...
人工智能实践的课程项目基于Tensorflow + Keras实现图像中文描述生成项目源代码+数据集+模型 图像中文描述问题融合了计算机视觉与自然语言处理两个方向,对图片输出一句话的描述。 描述句子要求符合自然语言习惯,...
B.4.2 控制数据元素357 B.4.3 编辑过程357 B.4.4 输入模式的过程359 B.4.5 编辑模式的过程360 B.5 详细设计结果364 B.5.1 编辑程序的详细结构364 B.5.2 类PASCAL伪码365 B.5.3 实现编辑程序的算法367
| | 使用SQL Server管理和查询数据(SQL Base).rar ( 15,548,740 B, ) | | | |---职业导向训练(COT) | | 职业导向训练(cot).rar ( 16,005,359 B, ) | | | |---计算机基础 | | 计算机基础.rar ( 45,987,218 B, ) | |...
| | JavaScript客户端验证和页面特效制作(JavaScript).rar ( 97,771,517 B, ) | | | |---SQL Server数据库设计和高级查询(SQL Advance) | | SQL Server数据库设计和高级查询(SQL Advance).rar ( 18,973,155 B, ) | ...