Construtores ou construtores? Nós raciocinamos em voz alta

Olá! Quero especular sobre a conveniência de usar construtores para objetos simples.



Para simplificar, usarei as anotações lombok:



@Value

@Builder



Depois de pesquisar um pouco, chegamos àquele construtor - Separa a construção de um objeto complexo de sua apresentação para que diferentes visualizações possam ser obtidas como resultado do mesmo processo de construção. É apenas para objetos complexos?



Vejamos um exemplo simples:



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


Uma aula bem simples. Na verdade, obtemos um objeto imutável que é inicializado por meio do construtor.



Mas, como podemos ver, todos os campos são anuláveis ​​e criar tais objetos não parecerá muito bom:



        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);
...


Certamente existem opções:



  1. Objetos com alguns campos de tipos diferentes podem ser entregues com vários construtores. Mas isso não resolve o problema da aula acima.
  2. Usar setters é subjetivo, confunde o código.




E o construtor?



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


Obtemos uma construção muito elegante de um objeto simples :



        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();
...
}


Porém, para usar jackson no projeto, é necessário adicionar nossa classe para que ela seja desserializada com sucesso:



@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 {

    }
}


Obtemos nossos prós e contras para ambas as abordagens:



builder:



+

1. O código se torna mais conciso.

3. null nos parâmetros do construtor não é notável.

2. Menos chance de confundir parâmetros do mesmo tipo.

-

1. Criamos um objeto extra que o GC como um todo irá remover com segurança, mas você não deve se esquecer dele.

2. Se necessário, use jackson - empilhe a classe.



construtor:



+

1. Empilha minimamente nossa classe, sem água.

2. Nenhuma criação de objetos desnecessários.

-

1. Muitas vezes, nulo chegará no construtor de tal objeto.

2. Existe a possibilidade de cometer um erro quando alguém altera o código.



Resultado



Com base na minha experiência, costumo usar construtores. O custo não é alto, mas a saída é um código agradável de ler.



E, claro, escreva testes para evitar o segundo ponto negativo do uso de construtores.



PS Este é meu primeiro artigo, serei grato por críticas e comentários construtivos.



All Articles