Comment accèderiez-vous aux propriétés d'un objet à l'intérieur d'une méthode d'objet?

Quel est le moyen "puriste" ou "correct" 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, vous feriez 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 éteint, ça fait un an que j'ai programmé en Java ...

EDIT:

Il semble que les gens supposent que je ne parle que 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 faire de variable / propriété public). Donc, je peux partir 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 setters, ce qui va à l'encontre de ce que j'ai appris. bien. C'est probablement un bon sujet pour une autre question ...

0
ajouté édité
Vues: 3

17 Réponses

Cela dépend de la façon dont la propriété est utilisée. Par exemple, disons que vous avez un objet étudiant qui a une propriété de nom. 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.

Disons maintenant que vous avez un compteur d'entiers privés dans votre objet qui compte le nombre de fois que le nom a été appelé. Vous pouvez ne pas utiliser la méthode Get à l'intérieur de l'objet car cela produirait un nombre incorrect.

0
ajouté
Que faire si vous ajoutez une sorte de booléen à l'accesseur comme: PHP: fonction publique getName ($ outsideCall = true) {if ($ outsideCall) {$ this-> incrementNameCalled (); } return $ this-> name; } puis depuis l'objet même, si vous appelez get name, vous pouvez l'empêcher d'incrémenter: PHP: $ name = $ this-> getName (false); Est-ce que je vais juste à la mer ici?
ajouté l'auteur cmcculloh, source
Si l'objet Etudiant est un objet métier / domaine, vous êtes en train de mélanger les détails de l'infrastructure. Idéalement, les objets métier / domaine ne doivent concerner que la logique métier / domaine.
ajouté l'auteur moffdub, source

Est-ce que je vais juste à la mer ici?

Peut-être;)

Une autre approche consisterait à utiliser une méthode privée / protégée pour faire le get (mise en cache / db / etc), et un wrapper public pour incrémenter le compte:

PHP:

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

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

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

PHP:

$name = $this->_getName();

De cette façon, vous pouvez toujours utiliser ce premier argument pour quelque chose d'autre (comme l'envoi d'un drapeau pour savoir s'il faut ou non utiliser des données mises en cache ici peut-être).

0
ajouté

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

Plus tard, vous pourriez vouloir changer la façon dont ce champ fonctionne. Peut-être qu'il devrait être calculé à la volée ou peut-être que vous aimeriez utiliser un type différent pour le magasin de soutien. Si vous accédez directement aux propriétés, un changement comme celui-ci peut casser énormément de code dans un gonflement.

0
ajouté

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

0
ajouté
@ euphoria83 Peut-être, mais cela ne l'empêche pas de se produire.
ajouté l'auteur Greg Hurlman, source
ne fait rien d'autre dans un setter autre que de définir la valeur de la propriété un exemple de mauvaise utilisation en Java.
ajouté l'auteur euphoria83, source

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é en utilisant le setter de propriété (éventuellement privé).

Personnellement, j'utilise uniquement le membre privé derrière lorsque cela ne le ferait pas tomber dans un état non souhaitable, comme lors de l'initialisation ou lorsque la mise en cache / chargement paresseux est impliqué.

0
ajouté

Comme indiqué dans certains des commentaires: Parfois, vous devriez, parfois vous ne devriez pas. La grande partie à propos des variables privées est que vous êtes capable de voir tous les endroits où ils sont utilisés lorsque vous changez quelque chose. Si votre getter / setter fait ce dont vous avez besoin, utilisez-le. Si cela n'a pas d'importance, vous décidez.

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

0
ajouté

Je peux me tromper parce que je suis autodidacte, mais je n'utilise JAMAIS des propriétés publiques dans mes classes Java, elles sont toujours privées ou protégées, de sorte que le code externe doit être accessible par les getters / setters. C'est mieux pour la 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.

0
ajouté

Si par "puriste" vous voulez dire "plus d'encapsulation", alors je déclare généralement tous mes champs comme privés, puis j'utilise this.field dans la classe elle-même, mais toutes les autres classes, y compris les sous-classes, accèdent aux getters.

0
ajouté

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

0
ajouté

If I won't edit the property I'll use a get_property() public method unless it's a special occasion such as a MySQLi object inside another object in which case I'll just public the property and refer to it as $obj->object_property.

Inside the object it's always $this->property for me.

0
ajouté

Je dirais qu'il vaut mieux utiliser les méthodes d'accesseur même dans l'objet. Voici les points qui me viennent immédiatement à l'esprit:

1) Cela devrait être fait dans le but de maintenir la 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 faire un traitement supplémentaire (c'est rare). Si c'est le cas, en accédant directement au champ, vous perdriez ce traitement supplémentaire et votre programme pourrait aller de travers si ce traitement devait toujours être effectué pendant ces accès.

0
ajouté

Je suis assez surpris de constater à quel point le sentiment est unanime que getters et les setters sont bons et bons. Je suggère l'article incendiaire par Allen Holub " Getters et Setters sont Mal ". Accordé, le titre est pour la valeur de choc, mais l'auteur fait des points valides.

Essentiellement, si vous avez getters et setters pour chaque champ privé, vous rendez ces champs aussi bons que publics. Vous seriez très difficile de changer le type d'un champ privé sans effets d'entraînement à chaque classe qui appelle ce getter .

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

Les getters et les setters encouragent également les utilisateurs de la classe à demander des 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 seriez mieux servi de simplement dire à l'objet de faire ce que vous alliez en premier lieu; Aussi connu comme l'idiome Expert en information .

Les getters et setters, cependant, sont des maux nécessaires à la limite des couches - UI, persistance, et ainsi de suite. Accès restreint aux composants internes d'une classe, tels que le mot clé friend de C ++, l'accès protégé par package de Java, l'accès interne de .NET et le Friend Class Pattern peut vous aider à réduire la visibilité de getters et les setters à ceux qui en ont besoin.

0
ajouté

La façon OO puriste est d'éviter les deux et de suivre la Loi de Demeter en utilisant le Dites Ne demandez pas .

Au lieu d'obtenir la valeur de la propriété de l'objet, qui couple étroitement les deux classes, utilise l'objet comme paramètre

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

Lorsque la propriété était un type natif, par ex. int, utilisez une méthode d'accès, nommez-le pour le domaine de problème pas le domaine de programmation.

  doSomethingWithProperty( this.daysPerWeek() ) ;

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

0
ajouté

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 change les données, la propriété va stocker.

0
ajouté

Champs privés avec des 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 seront utilisées plus d'une fois dans une méthode. Si et seulement si vous avez le reste de votre application totalement modifié, bousculé, et optimisé autrement à l'endroit où l'accès aux valeurs en passant par leurs propriétés assosciées est devenu un goulot d'étranglement (Et cela n'arrivera jamais, je vous garantis) devrait même commencer 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 sauvegarde au moment du design.

0
ajouté

PHP propose une myriade de façons de gérer cela, y compris les 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. Pas 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 des valeurs calculées) ressemble à des propriétés régulières
  5. Vous pouvez facilement définir une propriété d'objet qui n'est jamais définie nulle part, qui n'est alors pas documentée
0
ajouté

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

Prenant ceci à sa conclusion 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é, en particulier en appelant une autre méthode dans cet objet (qui accèdera directement à la propriété de toute façon puis la renvoyer) est un exercice inutile et inutile (ou ai-je mal compris? ).

0
ajouté
J'ai été poussé par le même besoin que vous aviez à commenter ... De plus, il a été répondu non fermé;)
ajouté l'auteur Egg Vans, source