tipos - parametros en java
Gestionar constructores con muchos parĂ¡metros en Java (8)
En algunos de nuestros proyectos, hay una jerarquía de clases que agrega más parámetros a medida que avanza en la cadena. En la parte inferior, algunas de las clases pueden tener hasta 30 parámetros, 28 de los cuales se pasan al superconstructor.
Reconozco que usar DI automático a través de algo como Guice sería agradable, pero debido a algunas razones técnicas, estos proyectos específicos están limitados a Java.
Una convención de organizar los argumentos alfabéticamente por tipo no funciona, porque si se refactoriza un tipo (el círculo que estaba pasando para el argumento 2 ahora es una forma), de repente puede estar fuera de servicio.
Esta pregunta puede ser específica y llena de "Si ese es su problema, lo está haciendo mal a nivel de diseño" críticas, pero solo estoy buscando cualquier punto de vista.
¿Puedes encapsular parámetros relacionados dentro de un objeto?
por ejemplo, si los parámetros son como
MyClass(String house, String street, String town, String postcode, String country, int foo, double bar) {
super(String house, String street, String town, String postcode, String country);
this.foo = foo;
this.bar = bar;
entonces podrías tener:
MyClass(Address homeAddress, int foo, double bar) {
super(homeAddress);
this.foo = foo;
this.bar = bar;
}
Bueno, usar el patrón de construcción podría ser una solución.
Pero una vez que llegue a 20 o 30 parámetros, supongo que existe una relación alta entre los parámetros. Entonces (como se sugiere) envolverlos en objetos de datos lógicamente sanos probablemente tenga más sentido. De esta forma, el objeto de datos ya puede verificar la validez de las restricciones entre los parámetros.
Para todos mis proyectos en el pasado, una vez que llegué al punto de tener demasiados parámetros (¡y eso fue 8, no 28!), Pude desinfectar el código creando un mejor modelo de datos.
Como está obligado a Java 1.4, si desea DI, Spring sería una opción muy decente. DI solo es útil en lugares donde los parámetros del constructor son servicios o algo que no varía durante el tiempo de ejecución.
Si tiene todos esos diferentes constructores debido al hecho de que desea opciones variables sobre cómo construir un objeto, debe considerar seriamente usar el patrón de Constructor.
El patrón de diseño del constructor podría ayudar. Considera el siguiente ejemplo
public class StudentBuilder
{
private String _name;
private int _age = 14; // this has a default
private String _motto = ""; // most students don''t have one
public StudentBuilder() { }
public Student buildStudent()
{
return new Student(_name, _age, _motto);
}
public StudentBuilder name(String _name)
{
this._name = _name;
return this;
}
public StudentBuilder age(int _age)
{
this._age = _age;
return this;
}
public StudentBuilder motto(String _motto)
{
this._motto = _motto;
return this;
}
}
Esto nos permite escribir código como
Student s1 = new StudentBuilder().name("Eli").buildStudent();
Student s2 = new StudentBuilder()
.name("Spicoli")
.age(16)
.motto("Aloha, Mr Hand")
.buildStudent();
Si dejamos fuera un campo obligatorio (presumiblemente el nombre es obligatorio), podemos hacer que el constructor del Estudiante arroje una excepción. Y nos permite tener argumentos predeterminados / opcionales sin necesidad de realizar un seguimiento de ningún tipo de orden de argumento, ya que cualquier orden de esas llamadas funcionará igual de bien.
La mejor solución es no tener demasiados parámetros en el constructor. Solo los parámetros realmente necesarios en el constructor son los parámetros que se necesitan para inicializar correctamente el objeto. Puede tener constructores con múltiples parámetros, pero también un constructor con solo los parámetros mínimos. Los constructores adicionales llaman a este simple constructor y luego a los setters para establecer los otros params. De esta forma puede evitar el problema de cadena con más y más params, pero también tiene algunos constructores de conveniencia.
Lo que probablemente quieras hacer es tener una clase de Constructor. Entonces harías algo como esto:
MyObject obj = new MyObjectBuilder().setXxx(myXxx)
.setYyy(myYyy)
.setZzz(myZzz)
// ... etc.
.build();
Consulte la página 8 y siguientes de esta presentación de Josh Bloch (PDF), o esta revisión de Java efectivo
Realmente puedo recomendar el uso de POJOBuilder o POJOBuilder cuando POJOBuilder el patrón del generador.
Refactorizar para reducir la cantidad de parámetros y la profundidad de tu jerarquía de herencia es prácticamente todo lo que se me ocurre porque, en realidad, nada va a ayudar a mantener rectos los parámetros de 20 y tantos. Tendrá que atender cada llamada mientras mira la documentación.
Una cosa que podría hacer es agrupar algunos parámetros lógicamente agrupados en su propio objeto de nivel superior, pero eso tiene sus propios problemas.