我已经失去了使用类似方法通过失败快速验证代码状态的次数:
public class PersonValidator {
public boolean validate(Person person) {
boolean valid = person != null;
if (valid) valid = person.givenName != null;
if (valid) valid = person.familyName != null;
if (valid) valid = person.age != null;
if (valid) valid = person.gender != null;
// ...and many more
}
}
它可以工作,但是由于有效的检查,它是一种充满重复性的蛮力方法。 如果您的代码样式对if语句强制使用大括号(为此,则为+1),则您的方法也将长三倍,并且每次向验证器中添加新检查时都会增长。
使用Java 8的新流API,我们可以通过采取if (valid)
的保护条件并制作一个通用的验证器来为您处理管道来改善这一点。
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;
public class GenericValidator implements Function {
private final List> validators = new LinkedList<>();
public GenericValidator(List> validators) {
this.validators.addAll(validators);
}
@Override
public Boolean apply(final T toValidate) {
// a final array allows us to change the boolean value within a lambda
final boolean[] guard = {true};
return validators.stream()
// only send the validator downstream if
// previous validations were successful
.filter(validator -> guard[0])
.map(validator -> validator.apply(toValidate))
// update the guard condition
.map(result -> {
guard[0] = result;
return result;
})
// Logically AND the results of the applied validators
.reduce(guard[0], (b1, b2) -> b1 && b2);
}
}
使用此方法,我们可以将Person验证器重写为所需验证的规范。
public class PersonValidator extends GenericValidator {
private static final List> VALIDATORS = new LinkedList<>();
static {
VALIDATORS.add(person -> person.givenName != null);
VALIDATORS.add(person -> person.familyName != null);
VALIDATORS.add(person -> person.age != null);
VALIDATORS.add(person -> person.gender != null);
// ...and many more
}
public PersonValidator() {
super(VALIDATORS);
}
}
PersonValidator
和您所有其他的验证器现在可以完全专注于验证。 行为没有改变-验证仍然很快失败。 没有样板,这是一件好事。
这个正在工具箱中进行。
翻译自: https://www.javacodegeeks.com/2015/01/fail-fast-validations-using-java-8-streams.html