2

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!

3 Answers3

1

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 Predicates.

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.

sisyphus
  • 6,174
  • 1
  • 25
  • 35
  • Thanks! I'd like to report multiple failures by logging them and then incrementing the counter for that failure. Is there a better way to do that than another? – aspiring_programmer Dec 07 '15 at 00:23
  • I'm going to go with the simple for loop as it seems that it will do what I want and is nice and readable. I'd upvote your answer but I don't have enough reputation yet! – aspiring_programmer Dec 07 '15 at 00:51
1

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

Raveesh Sharma
  • 1,486
  • 5
  • 21
  • 38
0

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.

  • is there a better way to write this loop using Java 8 style functional programming? – aspiring_programmer Dec 07 '15 at 00:33
  • I am somewhat old school and experience ha taught me that code needs to clear and simple ( the [KISS principle](https://en.wikipedia.org/wiki/KISS_principle) ). This aids maintainability and bug fixing. So I think that your straightforward for loop and rule methods is a better choice. I do not think any other approach would be more efficient, either. – StephenG - Help Ukraine Dec 07 '15 at 00:43
  • Great, I'll go with that then. Thank you! – aspiring_programmer Dec 07 '15 at 00:50