82 votes

Les Données publiques, les membres vs Getters, Setters

Je suis actuellement en train de travailler dans Qt et C++. Je vais avoir des classes qui a privé les membres de données et fonctions membres publiques. J'ai publics getters et setters pour les membres de données disponibles dans la classe.

Maintenant, ma question est, si nous avons des getters et setters pour les membres de données dans nos classes, quel est l'intérêt de faire ces données membres privées? Je suis d'accord d'avoir des données privées des membres dans les classes de Base semble logique. Mais à côté de ça, d'avoir privé les membres et leurs accesseurs et mutateurs ne semble pas être d'une logique pour moi.

Ou plutôt peut-on faire de toutes les variables en tant que public, de sorte qu'aucun besoin pour les getters et les setters à tous? Est-ce une bonne pratique d'avoir ces? Je sais avoir privé les membres de garantir que les données de l'abstraction, mais ayant des getters et setters réalité permet d'accéder à ces variables assez facilement. Toutes les indications sur ce sont les bienvenus.

79voto

jmucchiello Points 10521

Ni. Vous devriez avoir des méthodes qui font des choses. Si l'une de ces choses arrive à correspondre avec une variable interne qui est grand, mais il devrait y avoir rien que des télégraphes ce pour les utilisateurs de votre classe.

Données privées est privé de sorte que vous pouvez remplacer la mise en œuvre chaque fois que vous le voulez (et pouvez faire plein reconstruit, mais c'est une autre question). Une fois que vous laissez le Génie de la bouteille que vous trouverez impossible à remettre.

EDIT: Suite à un commentaire que j'ai fait à une autre réponse.

Mon point ici est que vous poser la mauvaise question. Il n'y a pas de meilleure pratique en matière d'utilisation des getters/setters ou d'avoir des membres du public. Il y a seulement ce qui est le mieux pour votre objet et comment il des modèles spécifiques du monde réel de la chose ou de l'imaginaire chose, peut-être dans le cas de jeu).

Personnellement getters/setters sont le moindre de deux maux. Car une fois que vous commencez à faire des getters/setters, les gens à cesser de créer des objets avec un œil critique envers ce que les données doivent être visibles et que les données ne doivent pas. Avec le public et les membres, c'est encore pire parce que la tendance devient pour tout public.

Au lieu de cela, examiner ce que l'objet fait et ce qu'il signifie quelque chose à cet objet. Puis de créer des méthodes qui fournissent une interface naturelle dans cet objet. Naturel interface consiste à exposer certaines propriétés internes à l'aide des getters et setters ainsi soit-il. Mais l'important, c'est que vous avez réfléchi à l'avance et créé les getters/setters pour la conception d'un motif justifié.

38voto

AndreyT Points 139512

Non, il n'est pas même à distance de la même chose.

Il existe différents niveaux de protection et de mise en œuvre de cacher qui peuvent être obtenus par les différentes approches d'une interface de classe:


1. Membre de données publiques:

  • fournit à la fois de lire et d'écrire (si ce n'est const) l'accès aux données membres
  • expose le fait que les données de l'objet de l'existence physique et qui est physiquement un membre de cette classe (permet de créer des pointeurs de pointeur de type de membre à membre des données)
  • fournit des lvalue l'accès aux données membres (permet de créer ordinaire des pointeurs pour les membres)


2. Une méthode qui renvoie une référence à un élément de données (éventuellement à une donnée membre privée):

  • fournit à la fois de lire et d'écrire (si ce n'est const) l'accès aux données
  • expose le fait que les données de l'objet existe physiquement, mais n'expose pas qu'il est physiquement un membre de cette classe, ils ne permettent pas de créer des pointeurs de pointeur de type de membre pour les données)
  • fournit des lvalue l'accès aux données (permet de créer ordinaire des pointeurs vers elle)


3. De lecture et/ou des méthodes de définition (éventuellement accéder à une donnée membre privée):

  • fournit à la fois en lecture et/ou l'accès en écriture à la propriété
  • ne pas exposer le fait que les données de l'objet de l'existence physique, encore moins physiquement présents dans cette classe, ils ne permettent pas de créer des pointeurs de pointeur de type de membre pour que les données, ou tout autre type de pointeurs pour cette question)
  • ne fournit pas de lvalue l'accès aux données ne permettent pas de créer ordinaire des pointeurs vers elle)

Les getter/setter approche ne permet pas de même exposer le fait que le bien est mis en œuvre par un objet physique. I. e. il y a peut-être pas de physique, membre de données derrière les getter/setter de la paire.

De prendre le dessus dans le compte, il est étrange de voir quelqu'un de prétendre qu'un getter et le setter de la paire est le même qu'un membre de données publiques. En fait, ils n'ont rien en commun.

Bien sûr, il y a des variations de chaque approche. Une méthode de lecture, par exemple, peuvent retourner const référence aux données, ce qui permettrait de le placer quelque part entre (2) et (3).

11voto

Justin Niessner Points 144953

Les accesseurs et Mutateurs vous permettent d'appliquer la logique à l'entrée/sortie de les membres privés, par conséquent, le contrôle de l'accès aux données (Encapsulation pour ceux qui connaissent leur OO termes).

Les variables publiques laisser votre classe de données ouvertes au public pour les non contrôlée et non validés de la manipulation qui est presque toujours de l'onu-souhaitable.

Vous avez à penser à ces choses à long terme. Vous ne pouvez pas avoir de validation (ce qui est pourquoi les variables semblent être une bonne idée), mais il y a une chance qu'ils vont être ajoutés en bas de la route. Ajoutant à l'avance les feuilles le cadre donc il y a moins de re-factoring en bas de la cap pour ne pas mentionner la validation de ne pas casser le code dépendant de cette façon).

Gardez à l'esprit, cependant, cela ne signifie pas que Chaque variable privée a besoin de sa propre getter/setter. Neil apporte un bon point dans sa banque exemple que, parfois, des Getters/Setters ne faisons tout simplement pas de sens.

11voto

Jerry Coffin Points 237758

Rendre les données publiques. Dans le (peu probable) de l'événement que vous effectuez un jour besoin de logique dans le "getter" ou de "poseur", vous pouvez modifier le type de données d'une classe proxy qui surcharges operator= et/ou operator T (où T=quel que soit le type que vous utilisez actuellement) pour mettre en œuvre la logique nécessaire.

Edit: l'idée que le contrôle de l'accès aux données constitue l'encapsulation est fondamentalement faux. L'Encapsulation est sur la façon de masquer les détails de la mise en œuvre (en général!) pas de contrôle de l'accès aux données.

L'Encapsulation est complémentaire à l'abstraction: l'abstraction qui traite de l'objet est visible de l'extérieur de comportement, alors que l'encapsulation traite avec de cacher les détails de la façon dont ce comportement est mis en œuvre.

À l'aide d'un getter ou un setter effectivement réduit le niveau d'abstraction et expose la mise en œuvre, nécessite le code client d'être conscient que cette classe implémente ce qui est logiquement "données" comme un couple de fonctions (les getter et setter). L'utilisation d'un proxy comme je l'ai suggéré ci-dessus fournit réel encapsulation, hormis un coin obscur de cas, il a complètement cache le fait que ce qui est logiquement un morceau de données est réellement mis en œuvre par l'intermédiaire d'un couple de fonctions.

Bien sûr, cela doit être conservé dans son contexte: pour certaines classes, les "données" n'est pas une bonne abstraction à tous. En règle générale, si vous pouvez fournir de plus haut niveau des opérations au lieu de données, c'est préférable. Néanmoins, il existe des classes pour lesquelles la plus utilisable abstraction est la lecture et l'écriture de données -- et quand c'est le cas, le (abstraite) de données devrait être visible comme toutes les autres données. Le fait que l'obtention ou la définition de la valeur peut impliquer plus qu'une simple copie de bits est un détail d'implémentation qui devraient être cachées à l'utilisateur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X