简体   繁体   English

使用流畅的接口来验证使用 java 8 的对象

[英]Use of fluent interfaces to validate objects using java 8

Im currently doing a side project to validate objects using java 8.我目前正在做一个辅助项目来使用 java 8 验证对象。

Currently I have this:目前我有这个:

  • An interface that is essencially a rewrite of the java 8 predicate interface:一个本质上是 java 8 谓词接口的重写的接口:

在此处输入图片说明

Then, I created the implementation of that same interface:然后,我创建了相同接口的实现:

在此处输入图片说明

And then this class is the result of my validation然后这个类是我验证的结果

在此处输入图片说明

The concrete object validation can be found here:具体的对象验证可以在这里找到:

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("");
  }
}

This works fine but what I want to do now is to limit the user to use the notNull verification first, and only after that validation all the methods like notEmpty or greaterThanZero will be available.这工作正常,但我现在想要做的是限制用户首先使用 notNull 验证,只有在验证之后,notEmpty 或 GreaterThanZero 等所有方法才可用。

I searched for fluent interfaces but don't know if it is the correct way to do it (want to do something like this: https://code-held.com/2019/04/29/robust-builder-pattern/ )我搜索了流畅的界面,但不知道这是否是正确的方法(想做这样的事情: https : //code-held.com/2019/04/29/robust-builder-pattern/

To summarise, I want to force the developer to validate if the object is null first and all the other methods go next, something like the chaining of the Stream API in java-8.Here is my customValidations.总而言之,我想强制开发人员先验证对象是否为空,然后再验证所有其他方法,类似于 java-8 中 Stream API 的链接。这是我的 customValidations。

在此处输入图片说明

You can't, not with how you do your methods: <K> GenericValidation<K> from(Predicate<K> predicate) .你不能,而不是你如何做你的方法: <K> GenericValidation<K> from(Predicate<K> predicate)

By doing so, you tell the developer he can pass any Java expressions: you can't validate the content of the expression at runtime, unlike you want to play with bytecode - which you don't.通过这样做,您告诉开发人员他可以传递任何 Java 表达式:您无法在运行时验证表达式的内容,这与您想使用字节码不同 - 而您不想使用字节码。

You need to enforce this using the compiler, for example:您需要使用编译器强制执行此操作,例如:

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

Or using types as shown below:或者使用如下所示的类型:

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

StringValidator1 only have isNotNull() and return StringValidator2 . StringValidator1只有isNotNull()并返回StringValidator2

That's how you would enforce the isNotNull() check with the compiler: by returning another type providing more services than the default.这就是您将如何使用编译器强制执行isNotNull()检查:通过返回提供比默认值更多服务的另一种类型。 Since StringValidator1 does not have isNotEmpty() , then the compiler would generate a compilation error by trying to call it.由于StringValidator1没有isNotEmpty() ,因此编译器会通过尝试调用它来生成编译错误。

You may read AssertJ code for how they do their fluent interface.您可以阅读AssertJ代码,了解它们如何实现流畅的界面。 There are of course other source code being fluent (and I think the most important part of "fluent", is that the compiler and IDE helps you in validating what you are doing).当然还有其他源代码是流畅的(我认为“流畅”最重要的部分是编译器和 IDE可以帮助您验证您在做什么)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM