I\'m re-writing some code, and I\'ve decided the way to recreate the class, as there are a fixed number of sheets, I\'m creating them as enums. This is a decision based on the r
Although it doesn't strictly conform to the builder pattern, the short answer is yes. Sort of.
The missing piece is not being able to call .build()
to instantiate the enum constant, because build() can't use new
. But you can get quite a few of the benefits of the builder pattern. And let's face it, you can't use static factory methods, and inline subclassing of enum constants is weird.
Here's an example using a Country enumeration.
package app;
import org.apache.commons.lang.StringUtils;
import javax.annotation.Nullable;
import java.util.EnumSet;
import java.util.Set;
import static app.Language.*;
import static com.google.common.base.Preconditions.*;
enum Language {
ITALIAN,
ENGLISH,
MALTESE
}
public enum Country {
ITALY(new Builder(1, "Italy").addLanguage(ITALIAN)),
MALTA(new Builder(2, "Malta").addLanguages(MALTESE, ENGLISH, ITALIAN).setPopulation(450_000));
final private int id;
final private String name;
final private Integer population;
final private Set languages;
private static class Builder {
private int id;
private String name;
private Integer population;
private Set languages = EnumSet.noneOf(Language.class);
public Builder(int id, String name) {
checkArgument(!StringUtils.isBlank(name));
this.id = id;
this.name = name;
}
public Builder setPopulation(int population) {
checkArgument(population > 0);
this.population = population;
return this;
}
public Builder addLanguage(Language language) {
checkNotNull(language);
this.languages.add(language);
return this;
}
public Builder addLanguages(Language... language) {
checkNotNull(language);
this.languages.addAll(languages);
return this;
}
}
private Country(Builder builder) {
this.id = builder.id;
this.name = builder.name;
this.population = builder.population;
this.languages = builder.languages;
checkState(!this.languages.isEmpty());
}
public int getId() {
return id;
}
public String getName() {
return name;
}
@Nullable
public Integer getPopulation() {
return population;
}
public Set getLanguages() {
return languages;
}
}
You can even put static factory methods in the builder if you have common ways to build a constant.
So it's not quite Bloch's builder, but it's pretty close.