Reputation: 103
I'm new to programming. I have a list of objects that I want to validate (not short circuit, but run a list of validation rules by each one).
Initially I had a huge if/else statement but it didn't look very pretty. I think something like this would be better:
foreach (object: objects) {
foreach (rule: validationRules) {
try {
rule.validate(object)
} catch {
// Write to log
// Increment counter for rule
}
}
}
I just don't know how to go about creating the validation rules. I'd like to use Java 8 predicates because I hear that's what I should be using, but I'm not sure how to go about doing it. I think I might create an interface with the rules and then an implementation with each rule defined and also the list of rules. Does this sound like a good way to go about solving this problem?
Thanks!
Upvotes: 2
Views: 5008
Reputation: 1486
I was thinking of using predicates to validate objects in my project and i came across this wonderful link https://gtrefs.github.io/code/combinator-pattern/ . Essentially, After following the tutorial closely, I rechanged a lot of portions of the code that I have written. Primarily, the proper use of predicates makes the SRP stand out and that is definitely the way to go forward. I have written a simple validator using predicates for objects and published it at https://github.com/Raveesh/QuickProgramsForFun/tree/master/javaValidators perhhaps it will be useful for you
Upvotes: 1
Reputation: 6392
I think you can use Predicate
to implement your rules. Because Predicate
is a single abstract method, a simple lambda can be used to implement it, and your validator can be primed with a list of Predicate
s.
public final class Validator {
private final List<Predicate<MyObject>> rules;
public final Validator(List<Predicate<MyObject>> rules) {
this.rules = rules;
}
public final validate(MyObject object) {
return rules.stream()
.map(Predicate::test)
.findAny(Boolean.FALSE).isPresent();
}
}
And you can initialise the class with whatever you need as lambdas.
The question then is whether you want to collect failures from multiple failures, reporting them all together, or just to stop on the first failure. There are a number of options there depending on your situation. You can use exceptions or can pass some kind of a failure collector around.
Upvotes: 2
Reputation: 965
Your for loop is a perfectly good idea.
The predicate idea depends on whether that's a useful way to do whatever you mean by validation. I generally advise people not to lock themselves into a particular "must use X" way of thinking before starting a problem. Plan to use whatever is simplest and/or most efficient, but focusing on a specific feature leads to a kind of "trying to screw with a hammer" mentality.
Predicates would not require a loop, but would not, I think, be a good choice for performance, as they would create new collections of objects if you use them to filter, which is a potentially expensive operation. A simple rule that is a method ( as your own sketch shows ) seems simpler, both conceptually and to maintain as code.
Upvotes: 0