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