Melhorando a qualidade do código com Lombok

Olá pessoal, hoje iremos ver como podemos melhorar a escrita do código Java evitando o famoso "Don't repeat your self", conhecido também como código boilerplate, isso tudo usando o projeto Lombok.

O famoso código boilerplate


O código boilerplate é aquele que a linguagem ou tecnologia, nos obriga a fazer para criar classes, métodos, e compor comportamentos aos nossos sistemas, no Java, temos muitos pontos que fazemos código boilerplate, as vezes nem percebemos, pois já estamos acostumados com a estrutura da linguagem.

Com a evolução da plataforma Java, vários recursos foram introduzidos, que nos ajudou a reduzir o famoso código boilerplate, tais como: Lambdas, Streams, Optional, Default Methods, etc.

Apesar da constante evolução da plataforma, ainda existem pontos que precisamos executar de forma manual, ou com a ajuda das IDEs, vamos avaliar alguns deles:
  • Getters/Setters;
  • Construtores;
  • Equals e HashCode;
  • toString();
  • Variáveis de log e depuração. 
Mas a grande vantagem da plataforma Java, é sua flexibilidade e extensibilidade, com isso podemos resolver esse tipo de problema utilizando frameworks que executam esse tipo de tarefa, que é o caso do Lombok.

Conhecendo o Lombok


O Lombok é um framework que permite a criação de códigos boilerplate de forma mais clara usando anotações, ele atua no processo de compilação, onde temos a instrução no bytecode (.class), mas no arquivo .java o código fica limpo contendo apenas as anotações.

Configurando o Lombok


A configuração do Lombok é bem simples, ele consiste em adicionar a dependência  no pom.xml, para compilação via maven, e executar um jar para compilação nas IDEs:

Maven:

1
2
3
4
5
6
 <dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.14</version>
  <scope>provided</scope>
 </dependency>

Eclipse IDE:
  • Execute o jar lombok.jar;
  • Na tela de configuração, indique o diretório de instalação da sua IDE.
Para mais detalhes sobre a instalação consulte:


Estudo de Caso 


Para analisar os ganhos no uso do Lombok, vamos analisar a classe abaixo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
public class Usuario{

 private String nome;
 private String cpf;
 private String rg;
 
 public Usuario() {}

 public Usuario(String nome, String cpf, String rg) {
  this.nome = nome;
  this.cpf = cpf;
  this.rg = rg;
 }

 public String getNome() {
  return nome;
 }

 public void setNome(String nome) {
  this.nome = nome;
 }

 public String getCpf() {
  return cpf;
 }

 public void setCpf(String cpf) {
  this.cpf = cpf;
 }

 public String getRg() {
  return rg;
 }

 public void setRg(String rg) {
  this.rg = rg;
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + ((cpf == null) ? 0 : cpf.hashCode());
  result = prime * result + ((nome == null) ? 0 : nome.hashCode());
  result = prime * result + ((rg == null) ? 0 : rg.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Usuario other = (Usuario) obj;
  if (cpf == null) {
   if (other.cpf != null)
    return false;
  } else if (!cpf.equals(other.cpf))
   return false;
  if (nome == null) {
   if (other.nome != null)
    return false;
  } else if (!nome.equals(other.nome))
   return false;
  if (rg == null) {
   if (other.rg != null)
    return false;
  } else if (!rg.equals(other.rg))
   return false;
  return true;
 }

 @Override
 public String toString() {
  return "Usuario [nome=" + nome + ", cpf=" + cpf + ", rg=" + rg + "]";
 } 

Esta classe possui 2 construtores, métodos Get/Set para os 3 atributos, equals(), hashcode() e toString(), repare que a classe não possui nenhuma lógica de negócio, mas mesmo assim possui uma grande quantidade de código.

Para garantir o funcionamento da classe vamos executar um caso de teste feito com JUnit:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class UsuarioTest {

 @Test
 public void criarUsuarioComSetterGetterTest(){
  
  Usuario usuario = new Usuario();
  
  usuario.setCpf("0123456789");
  usuario.setRg("9874563210");
  usuario.setNome("Usuario 1");
  
  Usuario usuario2 = new Usuario();
  
  usuario2.setCpf("9874563210");
  usuario2.setRg("0123456789");
  usuario2.setNome("Usuario 2");
  
  Assert.assertNotEquals(usuario, usuario2);
 }
 
 @Test
 public void criarUsuarioComConstrutorTest(){
  
  Usuario usuario  = new Usuario("0123456789", "9874563210", "Usuario 1");
  Usuario usuario2 = new Usuario("9874563210", "0123456789", "Usuario 2");
  
  Assert.assertNotEquals(usuario, usuario2);
 }
}


Melhorando o código com Lombok 


Vamos aplicar alguns recursos do Lombok visando reduzir muito do código acima, vamos usar as seguintes anotações:
  • @Getter/@Setter: Geração dos métodos Get/Set;
  • @EqualsAndHasCode: Criação dos métodos equals() e hashCode();
  • @NoArgsConstructor: Criação de um construtor sem argumentos;
  • @AllArgsContructor: Criação de um construtor com todos os atributos da classe;
  • @ToString: Criação do método toString().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
@AllArgsConstructor
@NoArgsConstructor
@ToString
@EqualsAndHashCode
public class Usuario{

 @Getter @Setter
 private String nome;
 
 @Getter @Setter
 private String cpf;
 
 @Getter @Setter
 private String rg;
}


Analisando o código acima, percebemos uma grande redução de códigos, reduzindo de 79 para apenas 15 linhas, veja no Outline do Eclipse a estrutura gerada:

Classe gerada após a compilação do .java
Será que podemos reduzir um pouco mais ? 
A resposta é sim, usando a anotação @Data, podemos retirar as anotações @Getter/@Setter, @ToString, @EqualsAndHashCode, nosso código ficará assim:


1
2
3
4
5
6
7
8
9
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Usuario{

 private String nome;
 private String cpf;
 private String rg;
}

Ao executar os testes todos são executamos normalmente, e agora temos um código muito mais simples com as mesmas funcionalidades da primeira versão apresentada. 

Outros recursos do Lombok


O Lombok possui muitos outros recursos que podemos usar dentro das aplciações Java, para mais detalhes dos recursos acesse a pagina oficial:


Aqui existem exemplos de todas as anotações que podem ser usadas para reduzir códigos boilerplate. das aplicações.

Conclusão


Vimos aqui o poder do framework Lombok, e que é possível escrever código Java simples e reduzir aqueles códigos boilerplate, que escrevemos sem perceber.

Podemos usar Lombok em tudo ? 
A resposta é depende, para cada cenário vale a pena analisar as características da sua classe e método, na maioria dos casos é possível utilizar.

Podemos customizar a geração do método ?
A resposta é sim, cada anotação possui vários atributos que podem ser utilizados para gerenciar o criação do recurso.

Até a próxima.

Referências




Comentários

Popular Posts

Criando arquivos de log com Log4J

Monitorando o Tomcat com Java VisualVM

Injeção de dependências em Java EE usando @Inject, @EJB e @Resource ?

Gerenciamento de Transações com EJB - Parte 2

AngularJS - Formatando Datas com o Filter Date

JBoss AS 7 - Instalação e Configuração

Configurando o arquivo application.properties do SpringBoot

Métodos Utilitários da Classe String

Criando Módulos e DataSources no Wildfly

Criando uma Aplicação com Spring Boot e MongoDB