在某些情况下,我们需要先验证输入数据,然后再将其发送到业务逻辑层进行处理,计算等。这种验证在大多数情况下是孤立完成的,或者可能包括与外部数据或其他输入的某些交叉检查。 看下面的示例,该示例验证用户输入的注册数据。

public void register(String email, String name, int age) {String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";Pattern pattern = Pattern.compile(EMAIL_PATTERN);List<String> forbiddenDomains = Arrays.asList("domain1", "domain2");if ( email == null || email.trim().equals("")){throw new IllegalArgumentException("Email should not be empty!");}if ( !pattern.matcher(email).matches()) {throw new IllegalArgumentException("Email is not a valid email!");}if ( forbiddenDomains.contains(email)){throw new IllegalArgumentException("Email belongs to a forbidden email");}if ( name == null || name.trim().equals("")){throw new IllegalArgumentException("Name should not be empty!");}
if ( !name.matches("[a-zA-Z]+")){throw new IllegalArgumentException("Name should contain only characters");}
if ( age <= 18){throw new IllegalArgumentException("Age should be greater than 18");}
// More code to do the actual registration
}

这种方法的循环复杂性确实很高,如果要验证的字段更多或添加实际的业务逻辑,则可能会变得更糟。 当然,我们可以将代码分为两个私有方法(validate,doRegister),但是几个if块将被移到私有方法的问题。 除此以外,该方法还要做很多事情,而且很难测试。 当我要求初级开发人员重构该代码并使之更具可读性,可测试性和可维护性时,他们像个外星人一样看着我:“我应该如何简化它。 我该如何替换这些if块?” 好了,这里的解决方案效果很好,遵循“单一责任模式”,使代码更易于阅读。

为了更好地理解解决方案,请将每个if块都视为验证规则。 现在是时候为这些规则建模了。

首先用一种方法创建一个接口。 用Java 8术语,它称为功能接口 ,如下所示。

public interface RegistrationRule{void validate();
}

现在是时候将每个验证检查转换为注册规则了。 但是在我们这样做之前,我们需要解决一个小问题。 我们的界面实现应该能够处理注册数据,但是如您所见,我们拥有不同类型的数据。 因此,我们这里需要将注册数据封装在单个对象中,如下所示:

public class RegistrationData{private String name;private String email;private int age;
// Setters - Getters to follow
}

现在我们可以改善功能界面:

public interface RegistrationRule{
void validate(RegistrationData regData);
}

并开始编写我们的规则集。 例如,让我们尝试实现电子邮件验证。

public class EmailValidatationRule implements RegistrationRule{private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@"+ "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";private final Pattern pattern = Pattern.compile(EMAIL_PATTERN);
@Overridepublic void validate(RegistrationData regData) {if ( !pattern.matcher(regData.email).matches()) {throw new IllegalArgumentException("Email is not a valid email!");}
}

显然,我们在上述类中隔离了电子邮件验证。 我们可以对初始实施的所有规则执行相同的操作。 现在,我们可以重新编写我们的注册方法以使用验证规则。

List<RegistrationRule> rules = new ArrayList<>();rules.add(new EmailValidatationRule());rules.add(new EmailEmptinessRule());rules.add(new ForbiddenEmailDomainsRule());rules.add(new NameEmptinessRule());rules.add(new AlphabeticNameRule());for ( RegistrationRule rule : rules){rule.validate(regData);}

为了变得更好,我们可以使用Factory模式和一个静态方法get()创建一个Rules类,该方法将返回规则列表。 我们的最终实现将如下所示

for ( RegistrationRule rule : Rules.get()){rule.validate(regData);
}

将我们的注册方法的初始版本与最终版本的注册方法进行比较会产生疑问。 我们的新版本更紧凑,更易读,当然也更具可测试性。 实际的检查已移至单独的类(也易于测试),并且所有方法仅做一件事(请始终牢记这一点)。

翻译自: https://www.javacodegeeks.com/2014/07/avoiding-many-if-blocks-for-validation-checking.html

避免许多if块进行验证检查相关推荐

  1. v-if 表单验证_避免许多if块进行验证检查

    v-if 表单验证 在某些情况下,我们需要先验证输入数据,然后再将其发送到业务逻辑层进行处理,计算等.这种验证在大多数情况下是孤立进行的,或者可能包括与外部数据或其他输入的一些交叉检查. 看下面的示例 ...

  2. 独家 | 一文读懂数据质量和验证检查(附代码)

    作者:Vinod Kumar 翻译:季洋 校对:王雨桐 本文约1600字,建议阅读8分钟. 本文主要讲述关于数据质量和验证检查的实例,以及运用Apache Spark和Scala采用编码来确保数据质量 ...

  3. 单例设计模式八种方式——5) 懒汉式(线程安全,同步代码块) 6) 双重检查 7) 静态内部类 8) 枚举

    懒汉式(线程安全,同步代码块)应用实例 优缺点说明: 1) 这种方式,本意是想对第四种实现方式的改进,因为前面同步方法效率太低, 改为同步产生实例化的的代码块 2) 但是这种同步并不能起到线程同步的作 ...

  4. 手机HTML拼图验证,jQuery支持移动端的滑动块拼图验证插件

    注:chrome本地预览有错位问题需要在服务端演示正常,本地预览请用火狐浏览器. jq_slideImage 使用 var mySlideImage = new SlideImageVerify('# ...

  5. mysql身份证号批判断正误_如何验证检查Excel表中身份证号码的正误

    展开全部 我们现在通行的身份证号为十八位号,前62616964757a686964616fe4b893e5b19e31333365646234六位是地区代码,第七至十四位是出生年月日代码,第十五.十六 ...

  6. TCP’s Congestion Control Implementation in Linux Kernel 文献阅读笔记

    TCP's Congestion Control Implementation in Linux Kernel 文献阅读笔记 作者:Somaya Arianfar Aalto University S ...

  7. oracle数据块一致性检查的4种方法

    什么是数据块一致性? 每一个数据块头部都有一个"校验和"字段 当数据块被写回磁盘前,Oracle会重新计算这个校验和 并记录到这个字段,最终写回磁盘 下次数据块被读入内存时,Ora ...

  8. 使用RMAN VALIDATE验证数据和备份

    在oracle中可以使用rman VALIDATE来检查数据库是否存在坏块,检测备份集是否有用, 特别是备份集,建议定期做VALIDATE 验证,避免备份失败造成数据库损失. 1.VALIDATE D ...

  9. Oracle corrupt block(坏块) 详解

    转自:http://blog.csdn.net/tianlesoftware/article/details/5024966 一. 坏块说明 1.1 相关链接 在看坏块之前,先看几个相关的链接,在后面 ...

最新文章

  1. CPU状态信息us,sy,ni,id,wa,hi,si,st含义
  2. 【职业规划和代码库设计】
  3. 如何卸载安装有问题的devexpress组件?
  4. Cloud for Customer元数据的加载
  5. Python有多火,来看一份24小时榜单,从入门到进阶
  6. XPath CheatSheet
  7. 使用ConnectivityManager 判断网络是否连接
  8. java网络编程习题_java练习题-网络编程
  9. python安装pygame教程_Pygame安装教程
  10. python进行回归方程显著性检验
  11. 【数据结构】leetcode707:python实现链表设计;leetcode142:环形链表
  12. 嵌入式开发培训怎么样?嵌入式开发培训多少钱
  13. 三分钟上马 ESP32 spiffs文件系统
  14. idea提示红色但是代码没有错误,编译通过
  15. Tailscale组成局域网(以文明6联机为例)
  16. 电平触发,边沿触发,脉冲触发
  17. Qt设置编码、样式文件、窗体居中和开机自启等方法
  18. VSPD虚拟串口工具无法删除添加的虚拟串口
  19. 美通企业日报 | 无锡国际生命科学创新园开园;本特勒与恒大汽车博世实现合作...
  20. Nginx使用场景及相关配置

热门文章

  1. SpringCloudGateway静态路由配置
  2. ❤️ 爆肝一个月!JAVA零基础入门总结(下)❤️
  3. springboot 单例_如何实现一个单例及优化
  4. 转: Springboot — 用更优雅的方式发HTTP请求(RestTemplate详解)
  5. 让CentOS能用yum自动安装rar和unrar
  6. java oca_OCA的Java拼图游戏第3部分
  7. arrays.sort(._Arrays.hashCode(Object [])与Objects.hash(Object…)
  8. rxjava 背压_背压加载文件– RxJava常见问题解答
  9. jdbc mysql驱动_MySQL JDBC驱动程序如何处理准备好的语句
  10. AWS Loft的数据库周