Lombok

#framework#java#outil

Lombok est une librairie sous licence MIT permettant de générer du code lors de la compilation des classes JAVA. A travers l’utilisation d’annotations, Lombok permet d’obtenir un code plus lisible et libère également le développeur de la longueur d’écriture des méthodes que l’on retrouve communément dans les classes objets et métiers d’un projet.

Comment installer Lombok

Lombok est actuellement disponible en version 1.16.18 sortie en juillet 2017. Les mises à jour régulières de la librairie témoignent de sa pérennité. Elle s’intègre facilement à un projet existant :

Utilisation avec Maven

Utilisation avec Gradle

Comment utiliser Lombok

Prenons une classe Java qui permet de gérer des informations simples d’un utilisateur : nom, prénom et âge.

Difficile de faire une classe plus simple que celle-ci ! Pourtant, elle comporte déjà environ 80 lignes. En tant que développeur, nous écrivons souvent ce type de classe dont la majeure partie est systématiquement structurée de la même façon. C’est ici que la mise en place de Lombok prend tout son intérêt.

@Getter et @Setter

L’utilisation des annotations @Getter et @Setter permet de ne plus s’occuper de l’écriture des accesseurs de la classe. Nous obtenons déjà un objet plus lisible :

Il est possible de rendre le getter d’une propriété « lazy », c’est-à-dire d’exécuter son affectation uniquement lors du premier appel. Pour cela, il suffit d’ajouter @Getter(lazy=true) sur la propriété, utilisé principalement sur les initialisations coûteuses en mémoire ou en processeur.

@Accessors

A l’utilisation de la classe, on remarque alors que les getters et les setters sont légèrement différents de ceux que nous avions écrits au préalable. En effet, nous obtenons pour le prénom : get_prenom() au lieu de getPrenom(). Ceci est dû au caractère « _ » que nous avons ajouté devant chaque propriété. Pour rester cohérent avec les éventuelles normes de codage du projet, il suffit d’ajouter dans le cas présent l’annotation @Accessors(prefix = « _ ») qui permet d’obtenir le getter getPrenom() initialement écrit.

@NoArgsConstructor et @AllArgsConstructor

Il est également possible de s’abstraire de l’écriture des constructeurs de classe. Dans le cas présenté ici, nous allons gérer un constructeur sans arguments, et un autre constructeur contenant l’initialisation de toutes les propriétés. Avec l’utilisation supplémentaire de ces deux annotations, nous obtenons l’équivalent de la classe de départ avec seulement une vingtaine de lignes :

A noter qu’il est possible de spécifier le niveau de visibilité du constructeur complet, en ajoutant à l’annotation l’information suivante :

@AllArgsConstructor(access = AccessLevel.PROTECTED)

Il peut arriver que les propriétés d’une classe soient définies en « static ». Dans ce cas, une erreur de compilation apparait. Ceci est dû au fait qu’une propriété « static » doit être initialisée. Pour éviter l’erreur de compilation, il faut ajouter l’argument « force = true » à l’annotation @NoArgsConstructor :

@NoArgsConstructor( force = true )

Ceci a pour effet d’initialiser les propriétés avec la valeur 0, false ou null.

@RequiredArgsConstructor(staticName= »of »)
Pour réaliser un constructeur plus spécifique, il est possible de déterminer quelles propriétés doivent être initialisées lors de l’instanciation de la classe. Pour cela, il suffit de suivre deux étapes :
– ajouter l’annotation @NonNull aux propriétés concernées
– ajouter l’annotation @RequiredArgsConstructor(staticName= « of »)

Où « of » correspond au nom du nouveau constructeur. Exemple avec notre classe :

Pour l’utiliser, on écrit un code semblable à :

UtilisateurBean vUtilisateur = UtilisateurBean.of(« admin ») ;

L’inconvénient est qu’il n’est pas possible avec cette méthode de définir plusieurs constructeurs particuliers. Pour cela, il reste toujours la solution de l’écriture manuelle.

@Builder

Cette annotation génère un « builder » permettant de ne plus être dépendant de l’ordre particulier des paramètres lors de l’instanciation d’une classe. Dans notre exemple, il est donc possible d’écrire le code suivant :

UtilisateurBean.builder().nom(«unNom»).prenom(«unPrenom»).build();

L’inconvénient est qu’aucune erreur de compilation n’est remontée si un paramètre est manquant. De plus, lors d’une revue de code par exemple, la recherche de la hiérarchie d’appel est plus contraignante à analyser.

@Equals @HashCode et @ToString

Ces annotations permettent à Lombok de générer respectivement les méthodes « equals », « hashcode » et « ToString ». L’intérêt d’utiliser ces annotations, en plus d’éviter de les coder, réside dans le paramétrage des attributs que l’on souhaite utiliser dans ces méthodes. Pour cela, il y a deux manières de faire : soit par sélection en utilisant le paramètre « of », soit par exclusion en utilisant le paramètre « exclude ». Il est possible ainsi de définir précisément le comportement souhaité de la classe. Voici deux exemples qui illustrent l’utilisation de ces annotations pour que les méthodes correspondantes ne prennent en compte que les propriétés « nom » et « prenom » :
– Méthode ToString() : @ToString(of = {« nom », « prenom »}) ou @ToString(exclude = {« age »})
– Méthode HashCode() : @HashCode(of = {« nom », « prenom »}) ou @HashCode(exclude = {« age »})
– Méthode Equals() : @Equals(of = {« nom », « prenom »}) ou @Equals(exclude = {« age »})

Conclusion

La plupart des environnements de développement proposent la réécriture de code permettant au développeur de ne pas coder manuellement les méthodes redondantes d’une classe métier Java. Un des principaux avantages qu’offre Lombok réside dans l’utilisation des annotations permettant d’améliorer la lisibilité du code, en ne générant les méthodes que dans les classes compilées. De plus, les classes gagnent en maintenabilité, par exemple lors de la modification d’un nom de variable qui ne se fait qu’au niveau de la propriété.
Il faut noter cependant quelques inconvénients. Une fois les annotations Lombok mises en place, la navigation dans la hiérarchie des appels (de getter et setter par exemple) n’est plus aussi directe. Sous Eclipse, une solution de contournement consiste à lancer les recherches depuis la vue « outlines ». De plus, la Javadoc est également très succincte. Il faut penser à écrire la documentation complète sur la propriété directement.

Un autre piège à éviter est celui de la surcharge d’annotation. En effet, cette solution populaire utilisée par de nombreux Frameworks comme Hibernate, Spring ou Lombok transforme nos classes en une pile d’annotations donnant un résultat parfois contraire à celui attendu, à savoir simplifier l’écriture et la compréhension.

Site internet : https://projectlombok.org/

 

Il est possible de retrouver l’intégralité de cet article dans le numéro 217 du mois d’Avril 2018 du magazine « Programmez ».