¿Cómo mejorar el patrón del constructor?
Recientemente busqué una forma de inicializar un objeto complejo sin pasar muchos parámetros al constructor. Lo intenté con el patrón de constructor, pero no me gusta el hecho de que no puedo comprobar en el momento de la compilación si realmente configuro todos los valores necesarios.
Patrón de constructor tradicionalCuando uso el patrón de construcción para crear miComplex
objeto, la creación es más "a prueba de tipos", porque es más fácil ver para qué se usa un argumento:
new ComplexBuilder()
.setFirst( "first" )
.setSecond( "second" )
.setThird( "third" )
...
.build();
Pero ahora tengo el problema, que puedo perder fácilmente un parámetro importante. Puedo comprobarlo dentro delbuild()
Método, pero eso es solo en tiempo de ejecución. En el momento de la compilación no hay nada que me advierta, si me perdí algo.
Ahora mi idea era crear un constructor, que me "recuerda" si me perdí un parámetro necesario. Mi primer intento se ve así:
public class Complex {
private String m_first;
private String m_second;
private String m_third;
private Complex() {}
public static class ComplexBuilder {
private Complex m_complex;
public ComplexBuilder() {
m_complex = new Complex();
}
public Builder2 setFirst( String first ) {
m_complex.m_first = first;
return new Builder2();
}
public class Builder2 {
private Builder2() {}
Builder3 setSecond( String second ) {
m_complex.m_second = second;
return new Builder3();
}
}
public class Builder3 {
private Builder3() {}
Builder4 setThird( String third ) {
m_complex.m_third = third;
return new Builder4();
}
}
public class Builder4 {
private Builder4() {}
Complex build() {
return m_complex;
}
}
}
}
Como puede ver, cada configurador de la clase de generador devuelve una clase de generador interno diferente. Cada clase de constructor interno proporciona exactamente un método de establecimiento y el último proporciona solo un método build ().
Ahora la construcción de un objeto de nuevo se ve así:
new ComplexBuilder()
.setFirst( "first" )
.setSecond( "second" )
.setThird( "third" )
.build();
... pero no hay manera de olvidar un parámetro necesario. El compilador no lo aceptaría.
Parámetros opcionalesSi tuviera parámetros opcionales, usaría la última clase de constructor internoBuilder4
para establecerlos como lo hace un constructor "tradicional", devolviéndose a sí mismo.