Fornisci questo articolo del dottor Dobbs , e in particolare il modello del costruttore, come possiamo gestire il caso di sottoclasse di un costruttore? Prendendo una versione ridotta dell'esempio in cui vogliamo sottoclassare per aggiungere l'etichettatura OGM, un'implementazione ingenua sarebbe:
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;
}
}
sottoclasse:
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;
}
}
Ora possiamo scrivere codice in questo modo:
GMOFacts.Builder b = new GMOFacts.Builder();
b.GMO(true).calories(100);
Ma, se sbagliamo l'ordine, tutto fallisce:
GMOFacts.Builder b = new GMOFacts.Builder();
b.calories(100).GMO(true);
Il problema è ovviamente che NutritionFacts.Builder
restituisce un NutritionFacts.Builder
, non un GMOFacts.Builder
, quindi come possiamo risolvere questo problema o esiste un modello migliore da usare?
Nota: questa risposta a una domanda simile offre le classi che ho sopra; la mia domanda riguarda il problema di garantire che le chiamate del builder siano nell'ordine corretto.
build()
produrre b.GMO(true).calories(100)
?