Combiner getters et setters

16

Les bibliothèques JavaScript telles que jQuery, combinent 'getters' et 'setters' dans l'interface de programmation par exemple:

 $('element').css({'color','blue'});

définira la couleur ou

 $('element').css();

obtiendra le css pour un élément.

Existe-t-il un nom pour un tel modèle et est-ce une bonne pratique à utiliser dans les applications?

yannis
la source

Réponses:

12

Martin Fowler l'a récemment nommé getter et setter surchargé dans cet article :

J'ai fouillé dans Javascript récemment et une chose qui m'a frappé est l'habitude d'utiliser le même nom de fonction pour un getter et un setter. Donc, si vous souhaitez connaître la hauteur de votre bannière dans jQuery, vous utiliserez $("#banner").height()et si vous souhaitez modifier la hauteur que vous utiliserez $("#banner").height(100).

Cette convention m'est familière, car elle a été utilisée par Smalltalk. Vous pouvez obtenir une valeur avec banner heightet la modifier avec banner height: 100. Savoir que c'était une convention de petite conversation suffit pour m'attendre à ce que j'aime ça, car j'ai un amour distant mais constant pour cette langue. Mais même les meilleures choses ont des défauts, et je ne peux pas cacher mon aversion pour ce style de codage ...

Malgré cette préférence, vous devez suivre les conventions de la langue avec laquelle vous traitez. Si je réécrivais Smalltalk, je l'emploierais toujours height:100pour conserver la cohérence avec les conventions de la langue. Javascript, cependant, n'est pas connu pour avoir des conventions fortes, donc ici je préférerais éviter cette convention, même si elle est utilisée par jQuery ...

louisgab
la source
1
Bien que je sois généralement d'accord avec la plupart des propos de Fowler, je ne suis pas d'accord avec son aversion pour cela. Son raisonnement est que JavaScript n'a pas de conventions fortes comme Smalltalk, ce qui le rend utilisable là-bas. Cependant, jQuery a des conventions fortes et JavaScript n'est pas jQuery. jQuery est un framework.
CaffGeek
@Chad, je dois être en désaccord avec votre lecture de cela. Son argument est qu'il manque d'explication et de cohérence. Il dit qu'il l'utilise dans Smalltalk parce que la cohérence avec les autres l'emporte sur ses préoccupations. Il ne prétend pas que les conventions de Smalltalk atténuent ou éliminent en quelque sorte le problème.
Winston Ewert
2

Cela s'appelle «surcharge de méthode» dans les langages OO ou «surcharge de fonction» dans les langages non OO.

Que ce soit ou non une bonne pratique est un sujet de débat presque autant que les getters / setters contre les membres du public. Ceux du côté des pour et des contre se sont probablement fait les dents sur les langues qui avaient cette fonctionnalité ou non et qui sont définies à leur manière. Je l'utilise et j'aime la pratique pour plusieurs raisons:

  • Le contexte dans lequel il est utilisé sépare assez bien l'un de l'autre.
  • Ajouter getou setajouter au nom de la méthode ajoute de la verbosité.
  • S'il y a plusieurs getters (par exemple, un pour int et un pour double), la modification du type dans le LHS d'une affectation ( int x = foo.bar()vs. double x = foo.bar()) ne nécessite pas de changement de code ( barAsInteger()vs. barAsDouble()) vers la droite si la classe fournit les deux. L'inconvénient de ceci est qu'il peut parfois être difficile de savoir exactement quelle méthode est appelée simplement en regardant le code.
Blrfl
la source
Il est également appelé "surcharge de fonction" en C ++.
DeadMG
Les deux termes s'appliquent à C ++ car il a à la fois des méthodes et des fonctions à nu.
Blrfl
1

Étant donné que JavaScript n'a pas de propriétés réelles (où la définition d'une valeur peut réellement exécuter du code), le motif est celui qui implémente l'idiome de la propriété. (Même si vous l'appelez autrement.)

Donc, dans les langues implémentant des propriétés réelles, vous feriez ceci à la place:

element.css = ...
x = element.css

Si vous deviez utiliser le modèle JavaScript dans un langage qui gère les propriétés, vous feriez quelque chose d'anormal. Ce ne serait probablement pas une bonne idée. Gérez les propriétés de la façon dont le langage est censé les gérer, afin de ne pas confondre les autres personnes qui travaillent avec vous.

John Fisher
la source
msgstr "où définir une valeur peut réellement exécuter du code". Ce n'est plus vrai en réalité. Cela fait partie de la spécification depuis ECMA 5
Demian Brecht
@Demian: Mais, JQuery fonctionne dans les navigateurs qui n'implémentent pas ECMA 5.
John Fisher
Je n'ai rien mentionné sur la compatibilité entre les navigateurs, juste que la citation est incorrecte telle qu'elle est écrite.
Demian Brecht
@Demian: Le texte "JavaScript n'a pas de propriétés réelles" est correct si vous supposez qu'il utilise les versions les plus courantes de JavaScript. Puisque nous discutons dans un contexte d'implémentation de JQuery, l'énoncé serait correct. Merci d'avoir souligné que les nouvelles versions de JavaScript ont de vraies propriétés.
John Fisher du
0

Je pense que tu cherches properties

thekip
la source
C'est le nom de la fonctionnalité fournie en C # (et peut-être d'autres langages .NET?) Qui est similaire à cela, mais ce n'est pas vraiment la même chose.
Thomas Owens
Wikipedia accepte cependant: en.wikipedia.org/wiki/Property_(programming)
thekip
Merci, pas vraiment vous pourriez avoir un mot à dire de cas où vous définissez ou obtenir un salaire de personnes dans une application person.salary('10000')ou person.salary()ou similaire.
yannis
1
Je ne vois pas comment. "Les propriétés sont lues et écrites comme des champs", ce qui n'est pas vrai dans l'exemple de l'article d'origine. Là, des appels de méthode explicites sont effectués. C'est très similaire, mais pas exactement le même.
Thomas Owens
1
@yannis Ce n'est pas correct. JavaScript a une syntaxe pour les propriétés, et ce n'est pas du tout ce que vous avez décrit dans la question d'origine. Voir en.wikipedia.org/wiki/Property_(programming)#JavaScript pour savoir comment implémenter et utiliser des propriétés en JavaScript.
Thomas Owens
0

Je suis un peu totalement contre cela pour une raison simple: une classe, une méthode ou une fonction devrait juste faire une chose - à mon avis, et combiner les getteretsetter méthode violera cette règle. Résultat:

  1. La returnvaleur de la fonction varie en fonction de l' exécution du getter ou du setter block. Celui-ci peut simplement vous entraîner dans un cauchemar de maintenabilité. Votre méthode ne doit renvoyer qu'un seul type de données / objet dans tous les cas - ou renvoyer null,false ou jeter un exceptionen cas d'erreur.
  2. L'écriture des tests unitaires sera plus difficile car la fonction est responsable de deux fonctionnalités totalement différentes.
  3. La rédaction de documentation pour une telle méthode ou fonction est plus difficile pour des raisons évidentes.
  4. Il ne sera pas cohérent lorsque plusieurs méthodes getter sont nécessaires - comme déjà mentionné dans la Blrflréponse.
Mahdi
la source