¿Constructores o constructores? Razonamos en voz alta

¡Hola! Quiero especular sobre la conveniencia de usar constructores para objetos simples.



Para simplificar, usaré las anotaciones lombok'a:



@Value

@Builder



Después de buscar en Google, obtenemos ese constructor : separa la construcción de un objeto complejo de su presentación para que, como resultado del mismo proceso de diseño, se puedan obtener diferentes vistas. ¿Es solo para objetos complejos?



Veamos un ejemplo simple:



@Value
public class Info {
    @Nullable String uuid;
    @Nullable String email;
    @Nullable String phone;
}


Una clase bastante sencilla. De hecho, obtenemos un objeto inmutable que se inicializa a través del constructor.



Pero, como podemos ver, todos los campos son anulables y la creación de tales objetos no se verá muy bien:



        final Info info1 = new Info(null, "email@email.com", "79998888888");
        final Info info2 = new Info("3d107928-d225-11ea-87d0-0242ac130003", null, null);
        final Info info3 = new Info("3d107928-d225-11ea-87d0-0242ac130003 ", "email@email.com", null);
...


Ciertamente hay opciones:



  1. Los objetos con algunos campos de diferentes tipos se pueden entregar con varios constructores. Pero eso no resuelve el problema de la clase anterior.
  2. Usar setters es subjetivo, desordena el código.




¿Y el constructor?



@Value
@Builder
public class Info {
    @Nullable String uuid;
    @Nullable String email;
    @Nullable String phone;
}


Obtenemos una construcción muy elegante de un objeto simple :



        final Info info1 = Info.builder()
                .uuid("3d107928-d225-11ea-87d0-0242ac130003")
                .phone("79998888888")
                .build();
        final Info2 info2 = Info.builder()
                .email("email@email.com")
                .phone("79998888888")
                .build();
...
}


Sin embargo, para usar jackson en el proyecto, es necesario agregar nuestra clase para que deserialice con éxito:



@Value
@Builder(builderClassName = "InfoBuilder")
@JsonDeserialize(builder = Info.InfoBuilder.class)
public class Info {
    @Nullable String uuid;
    @Nullable String email;
    @Nullable String phone;

    @JsonPOJOBuilder(withPrefix = "")
    public static class InfoBuilder {

    }
}


Obtenemos nuestros pros y contras para ambos enfoques:



constructor:



+

1. El código se vuelve más conciso.

3. Nulo en los parámetros del constructor no es visible.

2. Menos posibilidades de confundir parámetros del mismo tipo.

-

1. Creamos un objeto adicional que el GC en su conjunto eliminará de forma segura, pero no debe olvidarse de él.

2. Si es necesario, use jackson: apile la clase.



constructor:



+

1. Apila mínimamente nuestra clase, sin agua.

2. Sin creación de objetos innecesarios.

-

1. Muy a menudo, el nulo llegará al constructor de tal objeto.

2. Es posible cometer un error cuando alguien cambia el código.



Salir



Según mi experiencia, tiendo a utilizar constructores. El costo no es alto, pero el resultado es un código agradable de leer.



Y, por supuesto, escribe pruebas para evitar el segundo punto negativo de usar constructores.



PD: Este es mi primer artículo, estaré agradecido por las críticas y comentarios constructivos.



All Articles