我已经失去了使用类似方法通过失败快速验证代码状态的次数:
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);}@Overridepublic Boolean apply(final T toValidate) {// a final array allows us to change the boolean value within a lambdafinal 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