En fait, comme dans d'autres proposition, il faut essayer (et c'est parfois dur pour moi aussi) de ne pas penser à ce que ça pourrait permettre de pire mais de bien peser le pour et le contre.
Car sinon, on n'aurait jamais eu l'opérateur ternaire "? :" en Java !!!
[QUOTE=bassim;2781310]En Pascal , si je me rappelle bien on fait comme ça:
en java ça serait:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 with monObjet do begin setSomething(); setChose(); traitemant(); end;
Quand je me suis mis à Java, c'est l'une des premières choses que j'ai regrettées par rapport à Pascal/delphi. Je suis pour à 100%.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 with monObjet { setSomething(); setChose(); traitement(getChose()); }
J'aime bien ce genre de raccourci de code, souvent moins lisible, mais avec l'habitude...
C'est un raccourci de codeur de C, qui mettent tout un programme dans un for. Je ne l'utiliserai jamais, c'est une façon de comprendre la grammaire très différente, et à priori je ne vois pas pourquoi j'en empêcherai les autres.
Sauf qu'à trop faire ce genre de variance, je vais tirer la gueule le jour où il faudra débugguer le programme d'un collègue. Et dans le cadre des projets open-source, merci la sère-mi !
Donc contre.
J'ai voté contre car à mon humble avis c'est plus un problème de design d'une API plutôt qu'une feature à ajouter au niveau du langage lui même.
Si on veut ce genre de comportement, il suffit de retourner this sur les setter.
- pas d'apport significatif
- bonjour le debug pas à pas ... même en étalant sur plusieurs lignes, c'est très pénible
Contre. Il suffit d'écrire son builder autrement:
Code java : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 class Builder { Builder setSomething(Something x) { ...; return this; } Builder setOther(Other x) { ...; return this; } Thing result() { ... } } Thing thing = new Builder() .setSomething(something) .setOther(other) .result();
ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.
Sauf que le plus souvent, on souhaiterait utiliser ça sur des objets qui appartiennent a l'API JAVA ou à une bibliothèque que l'on ne maitrise pas. En plus les setter sont sencés retourner le type void.
Bref à par quelques rares objets comme les StringBuilders, c'est actuellement impossible de faire du chainage.
Je suis plutot contre.
Dans le livre de Deitel comment porgrammer en Java j'ai vu que l'invcation de methodes chaines on la gere avec les set en renvoyant this.
class Builder {
Builder setSomething(Something x) { … return this;}
Builder setOther(Other x) { … return this;}
}
Builder builder = new Builder();
builder.setSomething(something).setOther(other);
On aurait comme ca une invocation des methodes chaines.
Le problème, c'est que ca marche plus aussi facilement lorsqu'on a une autre classe qui étend Builder et qui rajouterait juste une méthode, setSubMethod().
Et on ne pourrait pas alors écrire
Car setSomething et setOther sont définis comme retournant Builder.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SubBuilder subbuilder = new SubBulder(); subbuilder.setSomething(something).setOther(other).setSubMethod(otherthing);
Avec la proposition suivante, on est sûr que la méthode retourne toujours bien l'objet courant. Et donc on peut vraiment écrire
builder.setSomething(something).setOther(other).setSubMethod(otherthing);
sans aucun problème.
Vincent
contre
des expressions dont la sémantique implicite serait
"[delete, close, … ](someObject).do_something_on_supposed_still_alive_object()"
seraient possibles…
(ou comment indiquer qu'une méthode "void" "invalide" un objet ou son contenu et implicitement retourne null plutôt que this…)
+ quelques craintes quant aux implications subtiles sur l'AOP…
Je suis contre.
1) Je trouve primo que faire des chaînages ne devraient pas faire partie des "best practices". Comme déjà dit, en cas d'exceptions ça devient difficile à debuger et en plus question lecture de code, ce n'est pas terrible. Alors ajouter des facilités pour des mauvaises habitudes, non.
2) void ce n'est pas this, ça ne tient pas debout. Pour les adeptes des chaînages vous n'avez qu'à retourner l'objet qu'il faut dans votre méthode.
3) Je vois vraiment pas le gain... C'est plus rapide? A quel point de vue? Relecture du code? Debugage? A part ajouter de l'incohérence dans le langage (void <> this), je vois pas trop ce que ça ferait...
Dans une utilisation raisonné ça peut améliorer la lisibilité du code. Il faut se donner des limites et je pense que cette amélioration peut être forte avantageuse.
En effet, peut-être que mon voisin ou l'intervenant ne saura pas respecter les règles de codage que je souhaites mettre en place dans mon service. Le rôle d'un chef de projet peut aussi passer par une revue de code hebdomadaire pour vérifier ces règles et faire des réajustements si nécessaire. Donc il me parait pertinent de pouvoir utiliser cette syntaxe qui, comme toutes les améliorations proposées dans V7 et dans les précédentes, ne sont pas obligatoirement utilisable. C'est une boite à outils qu'il faut réguler pour que la lisibilité et le debuggage du code soit cohérent pour tous les intervenants d'un projet.
Je vois pas en quoi ça peut apporter de la lisibilité (... .maMethode vs obj.maMethode) avec ce qui existe déjà, désolé... Encore une fois les chainages devraient être évités. Ou comme j'ai déjà dit, fait un return this dans tes setters, si ça démange tant que ça de faire des chaînage. En tout cas pour moi c'est une très mauvaise idée qui n'ajouterait que de l'incohérence au niveau de la logique, void c'est n'est pas this!!!
Contre.
void c'est void. Donc si le designer de la classe n'a pas prévu de retourner l'objet, il n'y a pas de raison de contourner ce choix.
Exactement, void c'est void. Si on veut construire choses comme objet.met1().met2(). ..., on peut bien changer les types, et retourner 'this' a la fin de chacune method.
Une méthode void peut très bien retourner l'instance meme. Ce code ne destabilise pas...
Partager