Skip to content
Han edited this page Oct 8, 2021 · 3 revisions

This library is primarily intended to be used to validate inputs/arguments of method calls or outputs from method calls, as part of some defensive strategy.

At the end of the day, it is entirely up to your how you wish to use it. The following are just my thoughts.

The output (in general usage) of the API will either be the value to be validated or a runtime exception with some message. Thus you will have to decide how to handle the exception.

This is intended for complex validation rules/logic applied to some object. If one rule is used, then best to use a guard clause.

This is a personal opinion but validation, in general, and not a hard rule, should not be done in the constructor (nor should any logic or method calls be in constructors - to get around this see https://www.yegor256.com/2015/05/07/ctors-must-be-code-free.html) but could be done in static factory methods. Also, validation should not be done everywhere, especially if we are in control of calling the method with parameters we know are correct.

As complex logic increases, and the number of different exceptions and messages do to, the method can become fairly big. Ways of getting around this include using a decorator pattern to house the validation logic, or extract to a private method. But again, if the validation is part of the logic of the object, then it is better it stays in place.

The logic is written in the methods (ie mustSatisfy or couldSatisfy) are predicates. So if they need to be complex, can use the predicate DSL to write them in a cleaner way than using logical operands. This might be needed as currently, the library only supports all ANDs (mustSatisfy) and all ORs (couldSatisfy). See an example here...

In general, when an exception is thrown, it is good practice to log it. This can be done using the consumer method provided in this library. Or you can catch the exception further up the stack and log it there. See an example here...

If you wish to only check if logic is valid or invalid, can use their namesake at the end of the builder. At this moment, you will still need to write an exception message for each validation logic, but later the API will be expended to avoid this. See an example here...

The implemented builder classes (see Valid8OrMustSatisfyAllRulesBuilder and Valid8OrCouldSatisfyAllRulesBuilder) are where the builder methods are implemented (setting the fields and validating the builder method arguments) and the logic for applying the validation logic is delegated to the ValidationLogic class. So when debugging, best to look in the ValidationLogic class, although this is fairly abstract and generic.

Clone this wiki locally