java - Comment accéderiez-vous aux propriétés d'objet à partir d'une méthode d'objet?

Translate

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écalé, cela fait un an que j'ai programmé en Java ...

ÉDITER:

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 une variable / propriété). Donc, je pars peut-être d'une fausse hypothèse dès le départ. Il semble que les gens 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 bien. C'est probablement un bon sujet pour une question différente cependant ...

This question and all comments follow the "Attribution Required."

Toutes les réponses

Translate

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 - utiliser les deux entraînera des problèmes de maintenance plus tard (par exemple, quelqu'un ajoute du code à un setter quiBesoinsà exécuter chaque fois que cette propriété est définie et que la propriété est définie en interne sans que le setter soit appelé).

La source
Translate

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

Plus tard, vous souhaiterez peut-être changer la façon dont ce champ fonctionne. Peut-être que cela devrait être calculé à la volée ou peut-être souhaitez-vous utiliser un type différent pour le magasin de support. Si vous accédez directement aux propriétés, un changement comme celui-ci peut briser énormément de code en un seul coup.

La source
Translate

Je suis assez surpris de voir à quel point le sentiment est unanimegetterset les setters sont beaux et bons. Je suggère l'article incendiaire d'Allen Holub "Les getters et les setters sont mauvais". Certes, le titre est pour la valeur de choc, mais l'auteur fait valoir des points valables.

Essentiellement, si vous avezgettersetsetterspour 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 pour chaque classe qui l'appellegetter.

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

Les obturateurs et les setters encouragent également les utilisateurs de la classe à demander à l'objet des données, à 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 dire simplement à l'objet de faire ce que vous alliez faire en premier lieu; également connu sous le nom deExpert en informationidiome.

Les getters et les setters, cependant, sont des maux nécessaires à la limite des couches - UI, persistance, etc. Accès restreint aux éléments internes d'une classe, tels que le mot-clé friend de C ++, l'accès protégé au package de Java, l'accès interne de .NET et leModèle de classe d'amispeut vous aider à réduire la visibilité degetterset ne s'adresse qu'à ceux qui en ont besoin.

La source
Translate

Cela dépend de la façon dont la propriété est utilisée. Par exemple, supposons que vous ayez un objet étudiant qui possède 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.

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

La source
Translate

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

  1. La validation peut être placée dans les setters (et les 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 à celle des 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, qui devient alors non documentée
La source
Translate

Est-ce que je vais juste trop loin ici?

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 pour cela qui incrémente le nombre:

PHP:

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

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

puis de 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 pour savoir s'il faut utiliser ou non les données mises en cache ici peut-être).

La source
Translate

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?

Prenant cela à sa conclusion, le getter devrait appeler un getter, qui devrait appeler un getter.

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

La source
Translate

Si par "puriste" vous entendez "la plupart des encapsulations", alors je déclare généralement tous mes champs comme privés et j'utilise ensuite 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 en utilisant les getters.

La source
Translate

je dirais qu'il est préférable d'utiliser les méthodes d'accesseur même dans l'objet. Voici les points qui me viennent immédiatement à l'esprit:

1) Cela doit être fait dans l'intérêt 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 cependant). Si tel est le cas, en accédant directement au champ, vous manqueriez ce traitement supplémentaire et votre programme pourrait mal tourner si ce traitement doit toujours être effectué lors de ces accès

La source
Translate

La manière puriste OO est d'éviter les deux et de suivreLoi de Déméteren utilisant leDites, ne demandez pasapproche.

Au lieu d'obtenir la valeur de la propriété de l'objet, quicouples serrésles deux classes, utilisez l'objet comme paramètre, par exemple

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

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

  doSomethingWithProperty( this.daysPerWeek() ) ;

Celles-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 maintenir toutes les pré-conditions ou invariants dépendants, mais ne tombez pas dans le piège de les nommer setters, revenez au principe d'Hollywood pour nommer lorsque vous utilisez l'idiome.

La source
Translate

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é stockera.

La source
Mel
Translate

Champs 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 seront utilisées plusieurs fois dans une méthode. Si et UNIQUEMENT si vous avez le reste de votre application si totalement modifié, secoué et autrement optimisé pour que l'accès aux valeurs en passant par leurs propriétés associées est devenu un goulot d'étranglement (et cela ne se produira JAMAIS, je vous le garantis) si vous commencez même d'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 de la conception.

La source
Translate

Si je ne modifie pas la propriété, j'utiliserai unget_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 publier la propriété et la désigner comme$obj->object_property.

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

La source
Translate

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

La source
Translate

Je peux me tromper parce que 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 les 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.

La source
Translate

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, je n'utilise le membre privé derrière que si cela ne ferait pas tomber l'objet dans un état moins que souhaitable, comme lors de l'initialisation ou lorsque la mise en cache / le chargement paresseux est impliqué.

La source
Dolores Lee
Translate

J'aime la réponse parcmcculloh, mais il semble que la réponse la plus correcte soitGreg Hurlman. Utilisez les getter / setters tout le temps si vous avez commencé à les utiliser depuis le getgo et / ou si vous êtes habitué à 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.

La source
Translate

Comme indiqué dans certains des commentaires: Parfois, vous devriez, 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 changez quelque chose. Si votre getter / setter fait quelque chose dont vous avez besoin, utilisez-le. Si cela n'a pas d'importance, vous décidez.

Le cas contraire 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.

La source