Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Builder pattern validation - Effective Java

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?

like image 610
Abhigyan Mehra Avatar asked Jul 03 '16 18:07

Abhigyan Mehra


People also ask

What is the advantage of builder pattern?

Advantages of the Builder pattern include: Allows you to vary a product's internal representation. Encapsulates code for construction and representation. Provides control over steps of construction process.

When should we use builder pattern in Java?

The builder pattern simplifies the creation of objects. It also simplifies the code as your do not have to call a complex constructor or call several setter methods on the created object. The builder pattern can be used to create an immutable class.

Is Builder pattern an anti pattern?

When Builder Is an Antipattern. Unfortunately, many developers pick only part of the Builder pattern — the ability to set fields individually. The second part — presence of reasonable defaults for remaining fields — is often ignored. As a consequence, it's quite easy to get incomplete (partially initialized) POJO.

When should builder pattern be used?

Builder pattern aims to “Separate the construction of a complex object from its representation so that the same construction process can create different representations.” It is used to construct a complex object step by step and the final step will return the object.


1 Answers

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.

like image 146
Sergey Kalinichenko Avatar answered Sep 24 '22 18:09

Sergey Kalinichenko