C’est quoi le projet Lombok ?
Lombok pour certaines personnes représente une île volcanique d’Indonésie, mais aussi c’est une libraire java qui se connecte automatiquement à votre éditeur et à des outils de construction, pimentant votre Java.
L’utilisation des annotations de Lombok est possible pour plusieurs méthodes (getters et setters, equals et hashcode, toString, constructeurs et modificateur d’accès)
1. Installation :
Plusieurs façons nous permettant vraiment de l’intégrer facilement pour nos projets, on peut le télécharger directement depuis cet URL https://projectlombok.org/download.html ou bien en utilisant Gradle, Maven ou autres outils.
avec Gradle :
dependencies {
compileOnly('org.projectlombok:lombok:1.18.22')
}
avec Maven :org.projectlombok
lombok
1.18.22
2. Démonstration :
Dans cet exemple, on va découvrir une petite comparaison entre un code sans Lombok et un code avec des annotations Lombok.
2.1 Sans Lombok :
public class Personne {
private String nom;
private String prenom;
private int age; public Personne() {
super();
}
public Personne(String nom, String prenom, int age) {
super();
this.nom = nom;
this.prenom = prenom;
this.age = age;
}
/**
* @return the nom
*/
public String getNom() {
return nom;
}
/**
* @return the prenom
*/
public String getPrenom() {
return prenom;
} /**
* @return the age
*/
public int getAge() {
return age;
} /**
* @param nom the nom to set
*/
public void setNom(String nom) {
this.nom = nom;
} /**
* @param prenom the prenom to set
*/
public void setPrenom(String prenom) {
this.prenom = prenom;
} /**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
} @Override
public int hashCode() {
return Objects.hash(age, nom, prenom);
} @Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Personne other = (Personne) obj;
return age == other.age && Objects.equals(nom,
other.nom) && Objects.equals(prenom,
other.prenom);
} @Override
public String toString() {
return “Personne [nom=” + nom + “, prenom=” + prenom
+“,age=” + age + “]”;
}
}
2.2 Avec Lombok :
@FieldDefaults(level=AccessLevel.PRIVATE)
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(of= {“nom”,”prenom”,”age”})
@ToString(of= {“nome”,”prenom”,”age”})
public class Personne implements Serializable {
// champs métier
String nom;
String prenom;
int age;
}
Passant maintenant à l’explication de ces annotations :
@FieldDefaults : permet de mettre un modificateur d’accès (pour notre cas (level=AccessLevel.PRIVATE) : mettre tous les champs en private
@NoArgsConstructor : cet annotation génère un constructeur sans argument et public
@AllArgsConstructor : on l’utilise pour la génération d’un constructeur avec tous les arguments et qu’il est public
@Getter : pour la génération des getters pour tous les champs
@Setter : pour la génération des setters pour tous les champs
@EqualsAndHashCode : permet la génération des méthodes equals et hashCode sur les champs donnés (on peut spécifier les champs avec (of=…))
@ToString(of=…) : cet annotation génère la méthode toString (on peut spécifier les champs avec (of=…)).
3. Pattern avec Lombok
Pour avancer plus avec le projet Lombok, on va s’attaquer à l’utilisation des patterns avec Lombok, pour cet article on va choisir les patterns Builder & Factory
3.1 Builder Pattern :
Le pattern Builder, comme indique le nom, permet la construction des objets complexes, il est nécessaire de l’utilisé lorsque nous voulons construire des objets immuable différents avec le même processus.
Avec Lombok la simple utilisation de l’annotation @Builder produit des API de construction complexe pour vos classes. @Builder
public class Personne {
private final String nom;
private final String prenom;
private final int age;
}
Et maintenant, Lombok fait tout le nécessaire pour nous, nous pouvant créer des Personne et le tester :
@Builder
Personne testPersonne = Personne.builder() .nom(“Henri”)
.prenom(“Alex”).age(25) .build();
assertThat(testPersonne.getNom()) .isEqualTo(“Henri”); assertThat(testPersonne.getAge()) .isEqualTo(25);
@Builder peut être placé sur une classe, ou sur un constructeur, ou sur une méthode. Alors que les modes « sur une classe » et « sur un constructeur » sont les cas d’utilisation les plus courants
3.2 Factory Pattern :
Parfois, il est nécessaire d’avoir un peu plus de contrôles pour la création des instances, notamment dans le Builder.
C’est toujours assez simple de le faire avec Lombok en utilisant la même annotation @Builder
@UtilityClass
public class PersonneFactory
{
@Builder(builderClassName="SmallBuilder",
builderMethodName="smallBuilder")
public static Personne newPersonne(String nom,
String prenom)
{
return Personne.builder().nom(nom)
.prenom(prenom)
.build();
}
@Builder(builderClassName="FullBuilder",
builderMethodName="fullBuilder")
public static Personne newVehicule(String nom,
String prenom,
int age)
{
return Personne.builder().nom(nom)
.prenom(prenom)
.age(age)
.build();
}
}
pour tester :
Personne p1 = PersonneFactory.smallBuilder()
.nom("Henri")
.prenom("Alex")
.build();
Personne p2 = PersonneFactory.fullBuilder()
.nom("Henri")
.prenom("Alex")
.age(25)
.build();
System.out.println(p1);
System.out.println(p2);
}
et ce qu’on aura dans la console
Personne(nom=Henri, prenom=Alex)
Personne(nom=Henri, prenom=Alex, age=25)
4. Quelques préconisations :
- Éviter l’utilisation de @Data car elle génère EqualsAndHashCode sur tous les champs, pareil pour ToString, ce qui peut occasionner des exécutions dans le cas des relations bidirectionnelles entre les classes.
- Vaut mieux utiliser @EqualsAndHashCode et @ToString en précisant les champs avec l’attribut of=…
- Faite attention aux logiciels de revue de code qui n’analysent pas le ByteCode mais que le code source.
Pour aller plus loin
Voici un lien officiel qui présente les caractéristiques de Lombok avec toutes les annotations : https://projectlombok.org/features/all