I thought that if getters would be good at the builder. The builder should generally not be used as the return value β the only way or class should be responsible for creating the object using the builder. Thus, a method (or class) should store the information it needs, and not return it.
For these reasons, I decided not to use any getters in the builder class. Builder only has setters (whether using Abc (...), setAbc (...) or abc (...)), build (), and possibly with some private methods like validate ().
Using the Product class, the sample object is as follows:
class Product { private final String color; private final int price; private Product(ProductBuilder builder) { this.color = builder.color; this.price = builder.price; }
The builder class is now an internal object class that allows me to use private constructors.
public static class ProductBuilder { private String color; private int price; private ProductBuilder() { } private ProductBuilder(Product entity) { this.color = entity.color; this.price = entity.price; } public ProductBuilder withColor(String color) { this.color = color; return this; } public ProductBuilder withPrice(int price) { this.price = price; return this; } public Product build() { return new Product(this.validate()); } private ProductBuilder validate() { if (color == null) { throw new IllegalStateException("color is null"); } return this; } }
As you can see, I added the builder() method to get the builder as a copy of the instance and emptyBuilder() as the factory method to hide the constructor (maybe there is a better name for it).
Also, when building an immutable class, make sure that everything inside is immutable too. Collections are complex, you need to make a copy, and then use Collections.unmodifiable * (...) on it so that no one references the collection lying under the unmodifiable shell.
EDIT . Presumably you need getters if you have an abstract superclass. This is an exaggeration. You need it only if you have a constructor with all the parameters. If you pass the builder instead, like me, you get:
class Product extends Something { ... private Product(ProductBuilder builder) { super(builder);
So do we need getters? This time, not really. We are all right with them. Some other ideas?