In Item 2 of Effective Java (2nd Edition), the author mentions the following about imposing invariants on parameters while using Builders:
It is critical that they be checked after copying the parameters from the builder to the object, and that they be checked on the object fields rather than the builder fields (Item 39). If any invariants are violated, the build method should throw an IllegalStateException (Item 60).
Does this imply that after the build method has created the target object, it should be passed to a validation routine for any required validations?
Also, could someone please explain the reasoning behind this?
Object validation is integral part of object creation using builders. Although you can have a separate routine doing the validation, such separation is not required: validation code could be part of the function doing the build. In other words, you can do this
TargetObject build() {
TargetObject res = new TargetObject();
res.setProperty1();
res.setProperty2();
validate(res); // This call may throw an exception
return res;
}
void validate(TargetObject obj) {
if (...) {
throw new IllegalStateException();
}
}
or this:
TargetObject build() {
TargetObject res = new TargetObject();
res.setProperty1();
res.setProperty2();
if (...) {
throw new IllegalStateException();
}
return res;
}
The important thing is that the validation takes place after, not before, the construction of the target object. In other words, you need to validate the state of the object, not the state of the builder.