J'ai entendu dire que ce n'était pas une bonne idée de travailler directement avec les attributs de la classe, mais plutôt d'utiliser des setters et des getters. Quelqu'un peut-il me dire pourquoi ?
Réponses
Trop de publicités?Il est amusant de constater que l'article de Wikipédia sur ce sujet donne de bonnes indications : http://en.wikipedia.org/wiki/Accessor
En bref, une classe doit utiliser des méthodes de mutateur (getters, setters, etc.) pour valider l'entrée avant qu'elle ne soit stockée de manière privée. Cela permet de s'assurer que l'on peut toujours compter sur la classe ailleurs dans le code.
En revanche, si l'attribut est disponible à l'échelle mondiale, n'importe qui peut le modifier. Si vous avez, par exemple, une chaîne de caractères qui doit avoir un format spécifique et que quelqu'un ajoute une valeur qui n'est pas correcte, des bogues peuvent en résulter.
En résumé, si vous codez en fonction d'interfaces (qui contiennent des getters et setters pour un champ privé), vous pouvez échanger n'importe quel objet conforme à l'interface. Les références externes aux champs de l'objet signifient que les utilisateurs externes connaissent l'implémentation. Cela crée un couplage entre le consommateur de l'objet et l'implémentation de l'objet, ce qui, dans ce cas, est une mauvaise chose.
Aujourd'hui, votre name
peut être stocké sous la forme d'un champ String
mais l'année prochaine, vous voudrez peut-être le mettre à jour avec un type plus intéressant ou obtenir l'information d'un autre endroit ou quoi que ce soit d'autre... qui sait ? L'utilisation d'un champ vous empêche de le faire. L'utilisation d'un accesseur vous permet de modifier l'implémentation comme vous le souhaitez. Ce principe est plus important que vous ne le pensez.
Ce qui suit pourrait vous intéresser : Coder pour les interfaces ?
Pour des changements simples au sein de la classe (membre bool), il est probablement plus rapide de le changer. Si c'est un peu plus compliqué (MyDate), vous voudrez peut-être mettre en place une validation.
La plupart des gens gardent les données des membres privées, c'est pourquoi les méthodes get/set doivent être utilisées pour modifier ces données depuis l'extérieur de la classe.
Il s'agit d'une convention, même si elle est forte.
Il est utilisé par la spécification JavaBean pour offrir une solution de contournement au fait que Java n'a pas de propriétés.
Il permet d'exprimer l'intention des attributs en lecture seule/écriture seule ou en lecture-écriture.
Il est très pratique de placer un point d'arrêt dans un setter pour voir pourquoi un attribut a changé de manière inexpliquée.
Comme nous l'avons déjà mentionné, les interfaces ne peuvent pas contenir d'attributs, mais peuvent définir des accesseurs.
Parfois, vous voudrez créer des attributs "virtuels", l'exemple classique étant les nombres complexes pour lesquels vous disposez des attributs x et y et offrez mod et angle par le biais de calculs dans les setters et getters.
De nombreuses API s'appuient sur cette convention pour déduire la signification de votre classe par réflexion.
Tous les IDE peuvent désormais les générer automatiquement, de sorte qu'ils ne me font plus autant mal aux doigts que par le passé.
Il existe deux raisons classiques d'interdire l'accès extérieur aux champs (attributs). Elles sont généralement abordées dans les cours d'introduction à la programmation OO.
- Si les données sous-jacentes sont privées, vous êtes libre de modifier l'implémentation dans la classe. Par exemple, disons que vous stockez un nombre complexe sous la forme d'une partie réelle et d'une partie imaginaire. Plus tard, vous décidez de changer cela pour stocker Z et theta (magnitude et angle). Si vous exposez les champs, la modification entraînera la rupture de toutes les classes qui interagissent avec eux. Si vous aviez utilisé des accesseurs, vous auriez pu implémenter getReal() et getImaginary() en termes de Z et de thêta sans rien casser.
- Vous pouvez ajouter d'autres opérations aux getters et (surtout) aux setters. Par exemple, vous pouvez suivre le nombre de modifications apportées à un champ, ou mettre à jour un autre champ en synchronisation avec lui, mais seulement si vous avez forcé toute classe qui veut modifier le champ à passer par un accesseur pour le faire. Avec un champ public, vous n'avez aucune chance de réaliser ces opérations.
- Réponses précédentes
- Plus de réponses