En java, ¿puedes usar el patrón de constructor con campos obligatorios y reasignables?
Esto está relacionado con la siguiente pregunta:
¿Cómo mejorar el patrón del constructor?
Tengo curiosidad por saber si es posible implementar un constructor con las siguientes propiedades:
Algunos o todos los parámetros son requeridosNingún método recibe muchos parámetros (es decir, no se proporciona una lista de valores predeterminados al método de fábrica del constructor inicial)Todos los campos del constructor se pueden reasignar un número arbitrario de vecesEl compilador debe verificar que todos los parámetros hayan sido configurados.Es correcto requerir que los parámetros se establezcan inicialmente en algún orden, pero una vez que se establece cualquier parámetro, todos los siguientes constructores pueden tener este conjunto de parámetros nuevamente (es decir, puede reasignar el valor de cualquier campo del generador que desee)No debe existir ningún código duplicado para los definidores (por ejemplo, no hay métodos de configuración que sobrescriban en los subtipos de constructor)A continuación se muestra un intento fallido (se omiten los constructores privados vacíos). Considere la siguiente implementación de Toy Builder, y tenga en cuenta que la línea con "Foo f2" tiene un error de compilación porque el establecedor heredado para un BuilderB, no un BuilderFinal. ¿Hay alguna manera de usar el sistema de tipo java para parametrizar los tipos de retorno de los configuradores para lograr los objetivos anteriores, o lograrlos de otra manera?
public final class Foo {
public final int a;
public final int b;
public final int c;
private Foo(
int a,
int b,
int c) {
this.a = a;
this.b = b;
this.c = c;
}
public static BuilderA newBuilder() {
return new BuilderC();
}
public static class BuilderA {
private volatile int a;
public BuilderB a(int v) {
a = v;
return (BuilderB) this;
}
public int a() {
return a;
}
}
public static class BuilderB extends BuilderA {
private volatile int b;
public BuilderC b(int v) {
b = v;
return (BuilderC) this;
}
public int b() {
return b;
}
}
public static class BuilderC extends BuilderB {
private volatile int c;
public BuilderFinal c(int v) {
c = v;
return (BuilderFinal) this;
}
public int c() {
return c;
}
}
public static class BuilderFinal extends BuilderC {
public Foo build() {
return new Foo(
a(),
b(),
c());
}
}
public static void main(String[] args) {
Foo f1 = newBuilder().a(1).b(2).c(3).build();
Foo f2 = newBuilder().a(1).b(2).c(3).a(4).build();
}
}