Joshua Bloch in his famous book Effective Java suggests the usage of the builder pattern when we are facing object creation with many parameters. Actually the builder pattern is a very handful technique to simulate the named optional parameters as found in Python.
As official Java documentation explains here https://docs.oracle.com/javase/tutorial/java/IandI/override.html “…if a subclass defines a static method with the same signature as a static method in the superclass, then the method in the subclass hides the one in the superclass.”
In order to overcome this constraint while implementing for example the Builder pattern we can utilize a technique which is called “Curiously recurring template pattern” and is an idiom in C++ in which a class X derives from a class template instantiation using X itself as template argument ( source https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). The “curiously-recurring” part refers to the fact that your class appears, rather curiously, in its own base class.
In the Java ecosystem this idiom renamed to “Curiously Recurring Generic Pattern” which means that although you can’t inherit directly from a generic parameter you can inherit from a class that uses that generic parameter in its own definition. Bruce Eckel explains the the Curiously Recurring Generic Pattern here https://www.artima.com/weblogs/viewpost.jsp?thread=133275 .
How we can utilize this in order to overcome static method hiding in the Builder pattern. Here is an example
First of all let’s declare the base DTO
public class KeyValueDTO implements Serializable { protected UUID id; protected String title; protected KeyValueDTO() { super(); } public KeyValueDTO(UUID id, String title) { super(); this.id = id; this.title = title; } public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
and a DTO that extends the base DTO
public class GuiTypeDTO extends KeyValueDTO { private String description; private GuiTypeDTO() { } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
The base abstract Builder is
public abstract static class Builder<T extends KeyValueDTO, B extends Builder<T, B>> { protected T dto; public Builder(T dto) { this.dto = dto; } public B withId(UUID id) { this.dto.setId(id); return self(); } public B withTitle(String title) { this.dto.setTitle(title); return self(); } public T build() { return dto; } protected abstract B self(); }
It is important to note the abstract method self() declared in the abstract Builder pattern.
Due to the static method hiding in java we cannot use the this operator in the subclass since it will result in error because the this operator will reference the static class Builder and the static class Builder has no methods of the subclass defined.
And the KeyValueDTOBuilder
public static class KeyValueDTOBuilder extends Builder<KeyValueDTO, KeyValueDTOBuilder> { protected KeyValueDTOBuilder() { super(new KeyValueDTO()); } @Override protected KeyValueDTOBuilder self() { return this; } }
We can see in the abstract Builder and in the KeyValueDTOBuilder the concept of “Curiously Recurring Generic Pattern”.
And finally the GuiTypeDTOBuilder
public static final class Builder extends KeyValueDTO.Builder<GuiTypeDTO, Builder> { private Builder() { super(new GuiTypeDTO()); } public Builder withDescription(String description) { this.dto.setDescription(description); return this; } @Override protected Builder self() { return this; } }
In this article we saw 2 techniques for implementing the inheritance in the static Builder pattern. The implementation combines the the abstract method self() declared in the abstract builder and the Curiously Recurring Generic Pattern that allows to us to declare the extended builders with generic parameters themselves.