【问题标题】:Use of fluent interfaces to validate objects using java 8使用流利的接口来验证使用 java 8 的对象
【发布时间】:2020-05-16 15:28:47
【问题描述】:

我目前正在做一个辅助项目来使用 java 8 验证对象。

目前我有这个:

  • 本质上是对 java 8 谓词接口的重写的接口:

然后,我创建了同一个接口的实现:

然后这个类就是我验证的结果

具体的对象验证可以在这里找到:

public class ConcreteValidator implements EmployeeValidator {
  @Override
  public void validate(Employee employee) throws EmployeeException {

    ValidatorUtil.notNullString.and(ValidatorUtil.notEmptyString)
        .and(ValidatorUtil.stringBetween(1, 100)).test(employee.getFirstName())
        .getFieldNameIfInvalid(" Please specify valid firstname ").orElse("");

    ValidatorUtil.notNullString.and(ValidatorUtil.notEmptyString)
        .and(ValidatorUtil.stringBetween(1, 100)).test(employee.getLastName())
        .getFieldNameIfInvalid(" Please specify valid lastname ").orElse("");

    ValidatorUtil.notNullString.and(ValidatorUtil.notEmptyString)
        .and(ValidatorUtil.stringBetween(3, 100)).test(employee.getEmail())
        .getFieldNameIfInvalid(" Please specify valid email ").orElse("");

    ValidatorUtil.notNullInteger.and(ValidatorUtil.greaterThanZero)
        .and(ValidatorUtil.integerBetween(18, 60)).test(employee.getAge())
        .getFieldNameIfInvalid(" Please specify valid age ").orElse("");
  }
}

这很好,但我现在要做的是限制用户首先使用 notNull 验证,只有在验证之后,所有方法,如 notEmpty 或 greaterThanZero 才可用。

我搜索了流畅的界面但不知道它是否是正确的方法(想做这样的事情:https://code-held.com/2019/04/29/robust-builder-pattern/

总而言之,我想强制开发人员首先验证对象是否为空,然后再执行所有其他方法,类似于 java-8 中 Stream API 的链接。这是我的 customValidations。

【问题讨论】:

  • 你应该复制代码而不是放图片。
  • 如果要求他们始终验证非空值,您可以简单地将其设为自动。验证器可以在应用任何其他验证之前检查非空,并且客户端不必指定非空检查。另外,请将代码输入为文本,而不是图像。

标签: java java-8 fluent


【解决方案1】:

你不能,而不是你的方法:<K> GenericValidation<K> from(Predicate<K> predicate)

通过这样做,您告诉开发人员他可以传递任何 Java 表达式:您无法在运行时验证表达式的内容,这与您想玩字节码不同——您不想玩。

您需要使用编译器强制执行此操作,例如:

GenericValidation<K> fromNonNull(Predicate<K> predicate) {
  return from(val -> val != null && predicate.test(val));
}

或者使用如下所示的类型:

validateThat(employee.getFirstName()) // return a StringValidator1
  .isNotNull() // return a StringValidator2
  .isNotEmpty()
  .hasLengthBetween(1, 100)
  ;

StringValidator1 只有isNotNull() 并返回StringValidator2

这就是您将如何使用编译器强制执行isNotNull() 检查:通过返回提供比默认更多服务的另一种类型。由于StringValidator1没有isNotEmpty(),那么编译器会通过调用它产生编译错误。

您可以阅读AssertJ 代码,了解他们如何实现流畅的界面。当然还有其他源代码是流利的(我认为“流利”最重要的部分是编译器和 IDE帮助你验证你在做什么)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    相关资源
    最近更新 更多