Progetto Java Lombok

Il progetto Lombok è un tool molto utile per i progetti Java per ridurre il codice boilerplate.

Dichiarazione del Problema

Nel dibattito Java vs. altri linguaggi, il primo argomento che ricevi dai sostenitori degli altri linguaggi è che Java richiede molto codice boilerplate e semplicemente non puoi superarlo, e sei indifeso. Lo stesso problema è riportato anche su diverse piattaforme e comunità di sviluppatori. Vediamo un esempio di codice che ha del codice boilerplate.

package com.askrakesh.java.manage_boilerplate;

import java.time.LocalDate;

public class Person {

	String firstName;
	String lastName;
	LocalDate dateOfBirth;

	public Person(String firstName, String lastName, LocalDate dateOfBirth) {
		super();
		this.firstName = firstName;
		this.lastName = lastName;
		this.dateOfBirth = dateOfBirth;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	public LocalDate getDateOfBirth() {
		return dateOfBirth;
	}

	public void setDateOfBirth(LocalDate dateOfBirth) {
		this.dateOfBirth = dateOfBirth;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((dateOfBirth == null) ? 0 : dateOfBirth.hashCode());
		result = prime * result + ((firstName == null) ? 0 : firstName.hashCode());
		result = prime * result + ((lastName == null) ? 0 : lastName.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;
		Person other = (Person) obj;
		if (dateOfBirth == null) {
			if (other.dateOfBirth != null)
				return false;
		} else if (!dateOfBirth.equals(other.dateOfBirth))
			return false;
		if (firstName == null) {
			if (other.firstName != null)
				return false;
		} else if (!firstName.equals(other.firstName))
			return false;
		if (lastName == null) {
			if (other.lastName != null)
				return false;
		} else if (!lastName.equals(other.lastName))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Person [firstName=" + firstName + ", lastName=" + lastName + "dateOfBirth=" + dateOfBirth + "]";
	}

}

A class should have getter-setters for the instance variables, equals & hashCode method implementation, all field constructors and an implementation of toString method. This class so far has no business logic and even without it is 80+ lines of code. This is insane.

Progetto Lombok

Il progetto Lombok è una libreria Java che si integra automaticamente nel tuo editor e negli strumenti di compilazione e aiuta a ridurre il codice boilerplate. Vediamo prima come configurare il progetto Lombok.

Come funziona il progetto Lombok in Java?

Lombok ha varie annotazioni che possono essere utilizzate nel nostro codice che viene elaborato durante il tempo di compilazione e si verifica l’espansione del codice appropriato in base all’annotazione utilizzata. Lombok riduce solo il codice durante la visualizzazione, dopo la compilazione il bytecode viene iniettato con tutto il boilerplate. Questo aiuta a mantenere il nostro codebase piccolo, pulito, facile da leggere e mantenere.

Progetto Lombok Maven

Aggiungere Lombok nel tuo progetto è semplice. Basta aggiungere la dipendenza sottostante nel file pom.xml del tuo progetto maven.

<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.16.20</version>
</dependency>

Aggiungere il plugin Lombok nell’IDE (Eclipse)

Ecco i passaggi di installazione per Windows:

  1. Scarica il jar da https://projectlombok.org/download o usa il jar scaricato dalla tua build maven.
  2. Esegui il comando nel terminale: java -jar lombok.jar
  3. Questo comando aprirà una finestra come mostrato nell’immagine sotto, installa e chiudi l’installer e riavvia Eclipse.

Se sei su MacOS, ecco i passaggi per utilizzare Lombok nel tuo progetto.

  1. Copia lombok.jar nella directory Eclipse.app/Contents/MacOS.
  2. Aggiungi -javaagent:lombok.jar alla fine del file Eclipse.app/Contents/Eclipse/eclipse.ini.
  3. Riavvia Eclipse e abilita “Elaborazione delle annotazioni” nelle proprietà del progetto come mostrato nell’immagine sottostante.

L’anteprima di Lombok in Eclipse

Dopo l’installazione, verifichiamo come possiamo vedere il nostro codice ridotto al minimo? Ho ricreato la stessa classe come PersonLombok. L’anteprima di Eclipse che mostra getter e setter per firstName. Questo è stato fatto basandosi sull’annotazione @Getter & @Setter di Lombok impostata per la variabile di istanza firstName.

L’anteprima di Lombok nel bytecode Java

Possiamo controllare l’aggiunta dei metodi getter & setter per il firstName dal bytecode della classe.

Annotation dei Progetti Lombok

Il progetto Lombok fornisce molte annotazioni che aiutano a ridurre il codice ripetitivo in vari scenari. Esaminiamone alcune.

  1. Annotation del Costruttore

    @AllArgsConstructor
    public class PersonLombok {
    	@NonNull String firstName;
    	String lastName;
    	LocalDate dateOfBirth;
    	public static void main(String[] args) {
    		new PersonLombok(null, "Kumar", LocalDate.now());
    	}
    }
    

    Il codice sopra inietta quanto segue nella classe:

    • Un costruttore con tutti gli argomenti tramite @AllArgsConstructor
    • Controllo di nullità durante il passaggio di un argomento nel costruttore tramite @NonNull. L’annotazione @NonNull può anche essere utilizzata quando si passa un argomento come parametro a un metodo

    Ecco il risultato dell’esecuzione del programma. @RequiredArgsConstructor genera un costruttore con 1 parametro per ogni campo che richiede un trattamento speciale. Tutti i campi finali non inizializzati ottengono un parametro, così come tutti i campi marcati come @NonNull che non sono inizializzati dove sono dichiarati.

  2. Annotazioni Getter/Setter

    Queste annotazioni possono essere utilizzate sia a livello di campo che di classe. Se desideri un controllo fine, utilizzale a livello di campo. Quando utilizzate a livello di classe vengono create tutte le getter/setter. Lavoriamo sulla classe che abbiamo creato sopra.

    @AllArgsConstructor @Getter @Setter
    public class PersonLombok {
    	String firstName;
    	String lastName;
    	LocalDate dateOfBirth;
    }
    
  3. Le annotazioni equals, hashCode e toString

    È consigliato sovrascrivere i metodi hashCode() e equals() durante la creazione di una classe. In Lombok abbiamo l’annotazione @EqualsAndHashCode che inietta del codice per il metodo equals() & hashCode() poiché vanno insieme. Inoltre, un’annotazione @ToString fornisce un’implementazione del metodo toString(). Vediamo questo:

    @AllArgsConstructor @Getter @Setter
    @EqualsAndHashCode 
    @ToString
    public class PersonLombok {
    	String firstName;
    	String lastName;
    	LocalDate dateOfBirth;
    }
    

    Ora abbiamo ottenuto di creare la classe Person senza alcun codice boilerplate grazie alle annotazioni di Lombok. Tuttavia, è ancora meglio: possiamo sostituire tutte le annotazioni utilizzate nella classe sopra con @Data e ottenere la stessa funzionalità.

  4. Annotationi basate su Design Pattern

    @Builder ti permette di produrre automaticamente il codice richiesto affinché la tua classe sia istanziabile usando il pattern builder.

    @Builder
    public class Dipendente {
    	String nome;
    	String cognome;
    	LocalDate dataDiNascita;
    
    	public static void main(String[] args) {
    		Dipendente dip = new EmployeeBuilder().firstName("Rakesh")
    				.lastName("Kumar")
    				.dateOfBirth(LocalDate.now())
    				.build();
    	}
    }
    

    @Delegate genera metodi delegati che inoltrano la chiamata a questo campo su cui è usata l’annotazione. “Preferisci la composizione all’ereditarietà”, ma questo crea molto codice boilerplate simile al pattern Adapter. Lombok ha preso spunto dall’annotazione di Groovy con lo stesso nome durante l’implementazione di questa funzionalità. Vediamo un’implementazione:

    @RequiredArgsConstructor
    public class AdapterImpl implements Adapter {
    	@Delegate
    	private final Adaptee instance;
    
    	public static void main(String[] args) {
    		AdapterImpl impl = new AdapterImpl(new Adaptee());
    		impl.display();
    	}
    }
    
    interface Adapter {
    	public void display();
    }
    
    class Adaptee {
    	public void display() {
    		System.out.println("In Adaptee.display()");
    	}
    }
    

    Lombok fornisce funzionalità per un controllo dettagliato in tutte le annotazioni.

Codice boilerplate: Gli architetti Java stanno ascoltando?

Sì, lo sono. È necessario comprendere che, a differenza di altri linguaggi, Java ha prestato la massima attenzione nell’aggiornare il linguaggio in modo tale da non compromettere alcun codice esistente che si trova nelle versioni precedenti di Java. Questo di per sé è un compito enorme e non può essere sottovalutato. Già stanno modificando e migliorando le capacità di inferenza dei tipi nel linguaggio, che è stato implementato. Una delle importanti caratteristiche pianificate per Java 10 è Inferenza del Tipo di Variabile Locale. Anche se la funzionalità ha più a che fare con l’aggiunta di tipizzazione dinamica rispetto al boilerplate, è comunque una piccola goccia nell’oceano per gestire il codice boilerplate.

Riepilogo

La riduzione del codice boilerplate aiuta a una migliore leggibilità, meno codice significa anche meno errori. Project Lombok è ampiamente utilizzato oggi in quasi tutte le principali organizzazioni. Ti abbiamo fornito le funzionalità più utili da Lombok. Speriamo che tu lo provi. Codice Sorgente: Puoi visitare il mio link di Github per scaricare il codice sorgente completo utilizzato in questo tutorial.

Source:
https://www.digitalocean.com/community/tutorials/java-project-lombok