There is a third variant too, with less code:
Instead of having their own instance fields the builders could also mutate the state of Vehicle
. Inner classes can write private members of their outer class:
class Vehicle {
private int wheels;
private Vehicle() {}
public static class Builder {
private boolean building = true;
private Vehicle vehicle = new Vehicle();
public Builder buildWheels(int wheels) {
if(!this.building) throw new IllegalStateException();
this.vehicle.wheels = wheels;
return this;
}
public Vehicle build() {
this.building = false;
return this.vehicle;
}
}
}
Since the fields are private and you allow it to be build only once (building
flag), built Vehicle
instances are still immutable to consumers even though the fields cannot be final
anymore (no more realio-trulio immutability, see Eric's blog article which is on C# but the concepts are similar).
You need to be more careful as non-final fields do not have to be initialized during object construction (enforced by the compiler) and you must check the building
state carefully. You do however save a full extra-copy of all instance fields. In general, this is useful if you have a rather large set of instance variables that are built with rather few methods, where each method builds a few fields at once.
I know this does not point out any advantages or drawbacks of your approaches. However, this approach can save a lot of extra code if you do not need the fields to be final
.