我目前正在做一个辅助项目,以使用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/)
总而言之,我想强迫开发人员首先验证对象是否为null,然后再验证所有其他方法,例如java-8中Stream API的链接。这是我的customValidations。
<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
helps >>来验证您的工作)。