Code

Project Lombok: una manna per ogni sviluppatore pigro

22 Maggio 2020 - 3 minuti di lettura

Bentrovati all’appuntamento settimanale della rubrica i3 Tips.

Protagonista è Lombok (1) ovvero una libreria open source abbastanza nota tra gli sviluppatori…pigri. L’utilizzo di questo aggettivo non è casuale, infatti grazie a questa utility è possibile risparmiare righe di codice e quindi tempo per lo sviluppatore che può concentrarsi su aspetti più importanti nello sviluppo.

Parola ad Alessandro D’Amico che ci mostra come portare a bordo la libreria in un progetto Java gestito con Maven (2) dopodiché mette a confronto la codebase di due classi per evidenziare i vantaggi del’utilizzo di Lombok.

Buona lettura.

Introduzione a Lombok

Boilerplate è un termine usato per descrivere il codice che viene ripetuto in molte parti di un’applicazione con poche modifiche. Una delle critiche espresse più frequentemente al linguaggio Java è che il volume di questo tipo di codice si trova nella maggior parte dei progetti. Questo problema è spesso il risultato di decisioni di design in varie librerie, ma è esacerbato dalle limitazioni del linguaggio stesso.

Lombok è una libreria di tipo Annotation processor (APT) ovvero durante la compilazione del progetto esegue l’interpretazione delle cosiddette annotation (@NomeAnnotazione per intenderci) dichiarate a livello di classe. In fase di compilazione Lombok esegue delle operazioni e genera in automatico il codice aggiuntivo.

E’ attraverso l’uso di annotation che avremo un risparmio di codice nonché di tempo, codice che sarebbe ripetitivo e difficile da mantenere.

Installazione della libreria Lombok

Supponendo che ogni sviluppatore usi un IDE, il mio consiglio è quello di installare il plugin disponibile per gli IDE più noti ovvero Eclipse (3), Visual Studio Code (4) e IntelliJ (5).

Di seguito un esempio per includere la dipendenza da installare nel vostro progetto Maven:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Qualora doveste usare altri tool di build come Gradle o Ant o altri IDE rimando alla lettura della pagina dedicata (6).

La vita del programmatore senza Lombok

L’esempio che vi voglio illustrare è la creazione di un Java Bean nel modo “classico”. Quindi creiamo una classe Dog con 2 campi.

import java.util.Objects;

public class Dog {

  private String name;

  private Integer age;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  @Override
  public boolean equals(Object o) {
    if (this == o) {
      return true;
    }

    if (o == null || getClass() != o.getClass()) {
      return false;
    }

    Dog dog = (Dog) o;

    return name.equals(dog.name) &&
      age.equals(dog.age);
  }

  @Override
  public int hashCode() {
    return Objects.hash(name, age);
  }

  @Override
  public String toString() {
    return "Dog{" +
      "name='" + name + '\'' +
      ", age=" + age +
      '}';
  }

}

Una nuova vita

Ora creeremo la stessa classe Dog ma utilizzando Lombok.

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dog {

  private String name;

  private Integer age;

}

Come avrete potuto notare con pochissime righe di codice siamo riusciti a creare lo stesso Bean.

Per l’esempio sono state usate tre annotation:

  • @NoArgsConstructor per generare un costruttore senza argomenti;
  • @AllArgsConstructor per generare un costruttore con tutti i campi dichiarati nel nostro Bean;
  • @Data che a sua volta include @ToString, @EqualsAndHashCode, @Getter / @Setter e @RequiredArgsConstructor.

Di seguito vi elenco altre annotation che spesso utilizzo:

  • @Getter e @Setter: per generare automaticamente i getter e i setter per ogni proprietà della classe;
  • @EqualsAndHashCode: per generare i metodi equals e hashCode della classe;
  • @ToString: per generare la rappresentazione testuale;
  • @RequiredArgsConstructor: per un costruttore con i campi richiesti (cioè i campi con final e @NonNull);
  • @Builder: genera il builder del Bean (esempio: Dog dog = Dog.builder().name("Beethoven").age(20).build(););

Per un ulteriore approfondimento rimando la lettura della pagina delle features (7).

Articolo scritto da