Comment la conception de JavaBeans correspond-elle à la dissimulation d'informations?
-
05-07-2019 - |
Question
Il y a deux semestres, un professeur m'a dit:
Certains d'entre vous ont été invités à toujours inclure les méthodes setter et getter pour toutes les variables d'instance privées. Je dis que cela brise la dissimulation d'informations et aboutit souvent à des systèmes où les invariants ne peuvent pas être appliqués.
Maintenant, cela me semble juste. Mais l'inclusion de ces types de setters / getters n'est-elle pas un élément essentiel de la création de JavaBeans? Si oui, pourquoi? Si non, qu'est-ce que je comprends mal à propos de JavaBeans?
La solution
Les getters et les setters ne sont pas requis dans une classe Java Bean. Tout ce qui est requis est que la classe soit publique, qu'elle ait un constructeur public sans argument et qu'elle implémente Serializable. Toutefois, pour que les variables soient automatiquement détectées lors de l’utilisation de votre bean, vous devez fournir des getters et des setters conformément à une convention de dénomination standard (getVarname, setVarname ...).
Dans tous les cas, vous souhaitez rendre visibles de manière externe uniquement les variables dont une entreprise est visible en dehors de votre classe.
Autres conseils
Vous pouvez lire Pourquoi choisir get et setter les méthodes sont diaboliques :
Vous pourriez objecter en disant: "Mais quoi à propos de JavaBeans? " Et eux? Vous peut certainement construire des JavaBeans sans Getters et setters. le
BeanCustomizer
,BeanInfo
et Les classesBeanDescriptor
existent toutes pour exactement ce but. Le JavaBean concepteurs de spécifications ont jeté le getter / setter idiome dans l'image parce qu'ils pensé que ce serait un moyen facile de faites rapidement une fève & # 8212; quelque chose que vous pouvez faites pendant que vous apprenez comment le faire droite. Malheureusement, personne ne l'a fait.Les accesseurs ont été créés uniquement comme moyen pour marquer certaines propriétés afin Programme UI-Builder ou équivalent pourrait identifiez-les. Vous n'êtes pas censé appelez ces méthodes vous-même. Ils existe pour un outil automatisé à utiliser. Cet outil utilise les API d'introspection dans la classe
Class
pour trouver les méthodes et extrapoler l'existence de certaines propriétés de la méthode des noms. En pratique, cela idiome basé sur l'introspection n'a pas élaboré. Ça fait énormément le code trop compliqué et procédural. Programmeurs qui ne comprennent pas les données abstraction appelle en fait le accesseurs, et par conséquent, la le code est moins facile à gérer.
C’est généralement assez simple, vous exposez les setters / getters pour les variables que vous devez rendre visibles à l’extérieur, et vous n’exposez pas les setters / getters pour les variables que personne ne connaît d’autre part.
Votre professeur a raison. Vous ne voulez pas créer aveuglément des getters et des setters pour toutes les variables d'instance. Vous voulez les créer là où ils sont requis.
Si vous avez une classe BankAccount
avec une variable d'instance balance
, il est judicieux de créer des getters et des setters si vous souhaitez pouvoir vérifier et définir la balance.
Même dans ce cas, des informations se cachent - sous la forme d’une encapsulation de la mise en œuvre. Le getter " double getBalance ()
" pourrait simplement renvoyer la valeur de la variable d'instance sous-jacente s'il s'agit d'un double
, ou renvoyer une valeur dérivée d'un BigDecimal
s'il s'agit du choix d'implémentation de la variable ou peut appeler un service Web distant et renvoyer le résultat. Ainsi, le getter / setter permet toujours que l’implémentation varie et ne viole donc pas l’encapsulation (et par extension, JavaBeans non plus).
Ce que JavaBeans fait pour vous, c'est définir une interface ( getXXX (), setXXX ()
) pour obtenir et définir les attributs de propriété d'une classe que les utilisateurs voudraient généralement examiner ou modifier. . Si votre classe dispose d'informations qui ne sont pas considérées comme une "propriété", il n'est pas nécessaire de les exposer. Par exemple, supposons que la classe BankAccount
ait une variable d'instance utilisée pour valider les retraits. Si le client n'a pas besoin de cet accès ou ne le modifie pas, il est inutile de créer un getter ou un configurateur.