Prenons un exemple avec un POJO tout simple
public class Article{ private String code; private String label; private Long version = Long.valueOf(0); private boolean active; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public Long getVersion() { return version; } public void setVersion(Long version) { this.version = version; } public boolean isActive() { return active; } public void setActive(boolean active) { this.active = active; } }
Maintenant si je veux valoriser les différentes propriétés d'une instance de cet objet je dois écrire
public class ArticleHelper { public Article createAndPopulateArticle(){ Article article = new Article(); article.setLabel("label"); article.setActive(true); article.setCode("code"); article.setVersion(1L); return article; } }
Sauf que dans nos applications de gestion, le nombre de propriétés est parfois assez conséquent et on se retrouve à écrire de grosses portions de code pour peupler un objet.
Reprenons notre POJO pour que chaque setter renvoie notre instance
public class Article{ private String code; private String label; private Long version = Long.valueOf(0); private boolean active; public String getCode() { return code; } public Article setCode(String code) { this.code = code; return this; } public String getLabel() { return label; } public Article setLabel(String label) { this.label = label; return this; } public Long getVersion() { return version; } public Article setVersion(Long version) { this.version = version; return this; } public boolean isActive() { return active; } public Article setActive(boolean active) { this.active = active; return this; } }
Maintenant la portion de code pour remplir les valeurs de l'objet est simplifiée.
public class ArticleHelper { public Article createAndPopulateArticle(){ return new Article().setLabel("label").setActive(true).setCode("code").setVersion(1L); } }
Je ne sais pas si cette pratique est très répandue, mais je trouve que dans mon cas, elle simplifie grandement des portions de mon code. Bon ce n'est pas demain que la convention sur les POJO avec leurs getter/setter changera mais si elle pouvait évoluer dans ce sens nous gagnerions en visibilité. Aujourd'hui nous utilisons tous les générateurs présents dans nos IDE pour créer les getter/setter de nos classes Java et cette pratique demande de revenir sur le code généré.
Hello,
RépondreSupprimerC'est cool de voir qu'on n'est pas les seuls à "évangéliser" cette pratique ;)
C'est une technique qui date déjà du smallTalk apparement (http://en.wikipedia.org/wiki/Method_chaining et http://en.wikipedia.org/wiki/Method_cascading) mais ça a du mal à décoller dans le monde java. Et pourtant le pattern builder l'utilise abondamment.
Pour mes 2cents, AMHA :
Avantages : code plus lisible, repenser l'API (services fournis, immutabilité, constructeurs...), penser utilisateur/appelant (car l'appel peut se faire dans un DSL un peu plus "naturel"), l'ecriture des tests facilité car plus besoin d'écrire les fameux builder (http://www.kenneth-truyers.net/2013/07/15/flexible-and-expressive-unit-tests-with-the-builder-pattern/) et en dernier le facteur humain (qui a besoin de stocker le résultat dans une variable intermédiaire pour le "voir")
Inconvénients : Temps alloué pour la reflexion (faux pbm), les frameworks qui ont besoin de leurs accesseurs/mutateurs des familles (hibernate, orika, ...), pas le même bytecode donc pas standardisé donc dès fois des debugs un peu fastidieux.
Pour les générateurs, il y a des plugin pour les IDEs ;)
Très bon blog en passant ;)
Haja
@hrambelo
Edit: Vous l'aurez compris que le facteur humain ci-dessus c'est plus un désavantage ...
RépondreSupprimer