Fail-fast Validations Using Java 8 Streams
Join the DZone community and get the full member experience.
Join For FreeI’ve lost count of the number of times I’ve seen code which fail-fast validates the state of something, using an approach like
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
}
}
It works, but it’s a brute force approach that’s filled with repetition due to the valid check. If your code style enforces braces for if statements (+1 for that), your method is also three times longer and growing every time a new check is added to the validator.
Using Java 8’s new stream API, we can improve this by taking the guard condition of if (valid) and making a generic validator that handles the plumbing for you.
import java.util.LinkedList;
import java.util.List;
import java.util.function.Predicate;
public class GenericValidator<T> implements Predicate {
private final List<Predicate<T>> validators = new LinkedList<>();
public GenericValidator(List<Predicate<T>> validators) {
this.validators.addAll(validators);
}
@Override
public boolean test(final T toValidate) {
return validators.parallelStream()
.allMatch(predicate -> predicate.test(toValidate));
}
}
Using this, we can rewrite the Person validator to be a specification of the required validations.
public class PersonValidator extends GenericValidator<Person> {
private static final List<Predicate<Person>> 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, and all your other validators, can now focus completely on validation. The behaviour hasn’t changed – the validation still fails fast. There’s no boiler plate, which is A Good Thing.
This one’s going in the toolbox.
Published at DZone with permission of Steve Chaloner. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments