Dê este artigo ao Dr. Dobbs e o Padrão do construtor em particular, como lidamos com o caso de subclassificar um construtor? Tomando uma versão resumida do exemplo em que queremos incluir uma subclasse para adicionar rotulagem de OGM, uma implementação ingênua seria:
public class NutritionFacts {
private final int calories;
public static class Builder {
private int calories = 0;
public Builder() {}
public Builder calories(int val) { calories = val; return this; }
public NutritionFacts build() { return new NutritionFacts(this); }
}
protected NutritionFacts(Builder builder) {
calories = builder.calories;
}
}
Subclasse:
public class GMOFacts extends NutritionFacts {
private final boolean hasGMO;
public static class Builder extends NutritionFacts.Builder {
private boolean hasGMO = false;
public Builder() {}
public Builder GMO(boolean val) { hasGMO = val; return this; }
public GMOFacts build() { return new GMOFacts(this); }
}
protected GMOFacts(Builder builder) {
super(builder);
hasGMO = builder.hasGMO;
}
}
Agora, podemos escrever código assim:
GMOFacts.Builder b = new GMOFacts.Builder();
b.GMO(true).calories(100);
Mas, se errarmos o pedido, tudo falhará:
GMOFacts.Builder b = new GMOFacts.Builder();
b.calories(100).GMO(true);
É claro que o problema NutritionFacts.Builder
retorna um NutritionFacts.Builder
, não um GMOFacts.Builder
, então como resolvemos esse problema ou existe um padrão melhor para usar?
Nota: esta resposta a uma pergunta semelhante oferece as classes que tenho acima; minha pergunta é sobre o problema de garantir que as chamadas do construtor estejam na ordem correta.
build()
produz a saída b.GMO(true).calories(100)
?