Comment accéderiez-vous aux propriétés d’un objet à partir d’une méthode objet ?[fermé]

StackOverflow https://stackoverflow.com/questions/126

  •  08-06-2019
  •  | 
  •  

Question

Quelle est la manière « puriste » ou « correcte » d'accéder aux propriétés d'un objet à partir d'une méthode objet qui n'est pas une méthode getter/setter ?

Je sais que de l'extérieur de l'objet, vous devriez utiliser un getter/setter, mais de l'intérieur, feriez-vous simplement :

Java:

String property = this.property;

PHP :

$property = $this->property;

ou feriez-vous :

Java:

String property = this.getProperty();

PHP :

$property = $this->getProperty();

Pardonnez-moi si mon Java est un peu décevant, cela fait un an que je n'ai pas programmé en Java...

MODIFIER:

Il semble que les gens supposent que je parle uniquement de variables/propriétés privées ou protégées.Quand j'ai appris OO, on m'a appris à utiliser des getters/setters pour chaque propriété, même si elle était publique (et en fait, on m'a dit de ne jamais rendre publique aucune variable/propriété).Donc, je pars peut-être d’une fausse hypothèse dès le départ.Il semble que les personnes qui répondent à cette question disent peut-être que vous devriez avoir des propriétés publiques et que celles-ci n'ont pas besoin de getters et de setters, ce qui va à l'encontre de ce qu'on m'a appris et de ce dont je parlais, même si cela doit peut-être être discuté comme suit. Bien.C'est probablement un bon sujet pour une question différente...

Était-ce utile?

La solution

Cela a un potentiel de guerre religieuse, mais il me semble que si vous utilisez un getter/setter, vous devriez également l'utiliser en interne - l'utilisation des deux entraînera des problèmes de maintenance plus tard (par ex.quelqu'un ajoute du code à un setter qui besoins à exécuter chaque fois que cette propriété est définie et que la propriété est définie en interne sans que ce setter soit appelé).

Autres conseils

Personnellement, je pense qu'il est important de rester cohérent.Si vous avez des getters et des setters, utilisez-les.La seule fois où j'accéderais directement à un champ, c'est lorsque l'accesseur a beaucoup de frais généraux.Vous aurez peut-être l'impression de gonfler votre code inutilement, mais cela peut certainement vous éviter bien des maux de tête à l'avenir.L'exemple classique :

Plus tard, vous souhaiterez peut-être modifier le fonctionnement de ce champ.Peut-être que cela devrait être calculé à la volée ou peut-être souhaiteriez-vous utiliser un type différent pour le magasin de support.Si vous accédez directement aux propriétés, un changement comme celui-là peut casser énormément de code en un seul coup.

Je suis assez surpris de voir à quel point le sentiment est unanime getters et les setters vont bien et bons.Je suggère l'article incendiaire d'Allen Holub "Les Getters et les Setters sont mauvais".Certes, le titre est choquant, mais l’auteur fait valoir des arguments valables.

En gros, si vous avez getters et setters pour chaque champ privé, vous rendez ces champs aussi bons que publics.Vous auriez beaucoup de mal à changer le type d'un champ privé sans effets d'entraînement sur chaque classe qui l'appelle getter.

De plus, d'un point de vue strictement OO, les objets devraient répondre à des messages (méthodes) qui correspondent à leur (espérons-le) unique responsabilité.La grande majorité de getters et setters n'ont pas de sens pour leurs objets constitutifs ;Pen.dispenseInkOnto(Surface) cela a plus de sens pour moi que Pen.getColor().

Les getters et setters encouragent également les utilisateurs de la classe à demander certaines données à l'objet, à effectuer un calcul, puis à définir une autre valeur dans l'objet, mieux connue sous le nom de programmation procédurale.Vous feriez mieux de simplement dire à l'objet de faire ce que vous alliez faire en premier lieu ;également connu sous le nom de Expert en information idiome.

Les getters et setters, cependant, sont des maux nécessaires à la frontière des couches : interface utilisateur, persistance, etc.Accès restreint aux éléments internes d'une classe, tels que le mot-clé ami de C++, l'accès protégé du package Java, l'accès interne de .NET et le Modèle de classe d'amis peut vous aider à réduire la visibilité de getters et les setters à ceux qui en ont besoin.

Cela dépend de la manière dont la propriété est utilisée.Par exemple, supposons que vous ayez un objet étudiant doté d’une propriété name.Vous pouvez utiliser votre méthode Get pour extraire le nom de la base de données, s'il n'a pas déjà été récupéré.De cette façon, vous réduisez les appels inutiles à la base de données.

Supposons maintenant que vous ayez un compteur entier privé dans votre objet qui compte le nombre de fois que le nom a été appelé.Vous souhaiterez peut-être ne pas utiliser la méthode Get depuis l'intérieur de l'objet, car cela produirait un décompte non valide.

PHP offre une myriade de façons de gérer cela, y compris des méthodes magiques __get et __set, mais je préfère les getters et setters explicites.Voici pourquoi:

  1. La validation peut être placée dans des setters (et des getters d'ailleurs)
  2. Intellisense fonctionne avec des méthodes explicites
  3. Aucune question de savoir si une propriété est en lecture seule, en écriture seule ou en lecture-écriture
  4. La récupération des propriétés virtuelles (c'est-à-dire les valeurs calculées) ressemble aux propriétés normales
  5. Vous pouvez facilement définir une propriété d'objet qui n'est jamais réellement définie nulle part, et qui n'est alors pas documentée.

Est-ce que je vais juste par-dessus bord ?

Peut-être ;)

Une autre approche consisterait à utiliser une méthode privée/protégée pour effectuer réellement l'obtention (mise en cache/db/etc), et un wrapper public qui incrémente le nombre :

PHP :

public function getName() {
    $this->incrementNameCalled();
    return $this->_getName();
}

protected function _getName() {
    return $this->name;
}

puis depuis l'intérieur de l'objet lui-même :

PHP :

$name = $this->_getName();

De cette façon, vous pouvez toujours utiliser ce premier argument pour autre chose (comme envoyer un indicateur indiquant s'il faut ou non utiliser les données mises en cache ici peut-être).

Je dois manquer le point ici, pourquoi utiliseriez-vous un getter à l'intérieur d'un objet pour accéder à une propriété de cet objet ?

En allant jusqu'au bout, le getter devrait appeler un getter, qui devrait appeler un getter.

Donc, je dirais qu'à l'intérieur d'une méthode d'objet, accéder directement à une propriété, d'autant plus qu'appeler une autre méthode dans cet objet (qui accédera de toute façon directement à la propriété puis la renverra) n'est qu'un exercice inutile et inutile (ou ai-je mal compris la question ).

Si par "puriste" vous entendez "la plupart des encapsulations", alors je déclare généralement tous mes champs comme privés, puis j'utilise this.field depuis la classe elle-même, mais toutes les autres classes, y compris les sous-classes, accèdent à l'état de l'instance à l'aide des getters.

je dirais qu'il est préférable d'utiliser les méthodes d'accès même au sein de l'objet.Voici les points qui me viennent immédiatement à l’esprit :

1) Cela doit être fait dans un souci de cohérence avec les accès effectués à l’extérieur de l’objet.

2) Dans certains cas, ces méthodes d'accès pourraient faire plus que simplement accéder au champ ;ils pourraient effectuer un traitement supplémentaire (c'est rare cependant).Si tel est le cas, en accédant directement au champ, vous passeriez à côté de ce traitement supplémentaire et votre programme pourrait mal tourner si ce traitement devait toujours être effectué lors de ces accès.

La méthode puriste de l'OO est d'éviter les deux et de suivre les Loi de Déméter en utilisant le Dites, ne demandez pas approche.

Au lieu d'obtenir la valeur de la propriété de l'objet, qui des couples serrés les deux classes, utilisez l'objet comme paramètre, par ex.

  doSomethingWithProperty() {
     doSomethingWith( this.property ) ;
  }

Lorsque la propriété était de type autochtone, par ex.int, utilisez une méthode d'accès, nommez-la pour le domaine problématique et non pour le domaine de programmation.

  doSomethingWithProperty( this.daysPerWeek() ) ;

Ceux-ci vous permettront de maintenir l'encapsulation et toutes les post-conditions ou invariants dépendants.Vous pouvez également utiliser la méthode setter pour conserver les conditions préalables ou les invariants dépendants, mais ne tombez pas dans le piège de les nommer setters, revenez au principe hollywoodien pour nommer lorsque vous utilisez l'idiome.

j'ai trouvé que l'utilisation de setters/getters rendait mon code plus facile à lire.J'aime aussi le contrôle qu'il donne lorsque d'autres classes utilisent les méthodes et si je modifie les données que la propriété stockera.

Terrains privés avec propriétés publiques ou protégées.L'accès aux valeurs doit passer par les propriétés, et être copié dans une variable locale si elles doivent être utilisées plus d'une fois dans une méthode.Si et SEULEMENT si le reste de votre application est totalement peaufiné, optimisé et autrement optimisé au point où l'accès aux valeurs en passant par leurs propriétés associées est devenu un goulot d'étranglement (et cela n'arrivera JAMAIS, je vous le garantis) si vous commencez même envisager de laisser autre chose que les propriétés toucher directement leurs variables de support.

Les développeurs .NET peuvent utiliser des propriétés automatiques pour appliquer cela, car vous ne pouvez même pas voir les variables de support au moment de la conception.

Si je ne modifie pas la propriété, j'utiliserai un get_property() méthode publique sauf s'il s'agit d'une occasion spéciale telle qu'un objet MySQLi à l'intérieur d'un autre objet, auquel cas je vais simplement rendre publique la propriété et y faire référence comme $obj->object_property.

À l'intérieur de l'objet, c'est toujours $this->property pour moi.

Ça dépend.C'est plus une question de style qu'autre chose, et il n'y a pas de règle stricte.

Je peux me tromper car je suis autodidacte, mais je n'utilise JAMAIS de propriétés publiques dans mes classes Java, elles sont toujours privées ou protégées, de sorte que le code extérieur doit y accéder par des getters/setters.C'est mieux à des fins de maintenance/modification.Et pour le code de classe interne...Si la méthode getter est triviale, j'utilise la propriété directement, mais j'utilise toujours les méthodes setter car je pourrais facilement ajouter du code pour déclencher des événements si je le souhaite.

Eh bien, il semble qu'avec l'implémentation par défaut des propriétés C# 3.0, la décision est prise pour vous ;vous DEVEZ définir la propriété à l'aide du setter de propriété (éventuellement privé).

Personnellement, je n'utilise le membre privé derrière que lorsque ne pas le faire entraînerait la chute de l'objet dans un état moins que souhaitable, comme lors de l'initialisation ou lorsque la mise en cache/le chargement paresseux est impliqué.

J'aime la réponse de cmcculloh, mais il semble que la réponse la plus correcte soit celle de Greg Hurlman.Utilisez les getter/setters tout le temps si vous avez commencé à les utiliser depuis getgo et/ou si vous avez l'habitude de travailler avec eux.

En passant, je trouve personnellement que l'utilisation de getter/setters rend le code plus facile à lire et à déboguer plus tard.

Comme indiqué dans certains commentaires :Parfois vous devriez le faire, parfois vous ne devriez pas.L’avantage des variables privées est que vous pouvez voir tous les endroits où elles sont utilisées lorsque vous modifiez quelque chose.Si votre getter/setter fait quelque chose dont vous avez besoin, utilisez-le.Si cela n'a pas d'importance, c'est vous qui décidez.

Le cas inverse pourrait être celui où si vous utilisez le getter/setter et que quelqu'un change le getter/setter, il doit analyser tous les endroits où le getter et le setter sont utilisés en interne pour voir s'il gâche quelque chose.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top