Presente este artículo del Dr. Dobbs , y el Patrón del constructor en particular, ¿cómo manejamos el caso de subclasificar un Constructor? Tomando una versión reducida del ejemplo donde queremos subclasificar para agregar el etiquetado de OGM, una implementación ingenua sería:
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;
}
}
Subclase:
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;
}
}
Ahora, podemos escribir código como este:
GMOFacts.Builder b = new GMOFacts.Builder();
b.GMO(true).calories(100);
Pero, si nos equivocamos en el pedido, todo falla:
GMOFacts.Builder b = new GMOFacts.Builder();
b.calories(100).GMO(true);
El problema es, por supuesto, que NutritionFacts.Builder
devuelve un NutritionFacts.Builder
, no un GMOFacts.Builder
, entonces, ¿cómo resolvemos este problema, o hay un mejor patrón para usar?
Nota: esta respuesta a una pregunta similar ofrece las clases que tengo arriba; Mi pregunta es sobre el problema de garantizar que las llamadas del constructor estén en el orden correcto.
build()
la salida de b.GMO(true).calories(100)
?