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, 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 décalé, cela fait un an que je programme 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 ...
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 votre code inutilement, 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. Il devrait peut-être ê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
Je suis assez surpris de voir à quel point le sentiment est unanime
getters
et que les setters sont bons et bons. Je suggère l'article incendiaire d'Allen Holub " Getters And Setters Are Evil ". Certes, le titre est pour la valeur de choc, mais l'auteur fait valoir des points valables.Essentiellement, si vous avez
getters
etsetters
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 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é
getters
etsetters
n'ont pas de sens pour leurs objets constitutifs;Pen.dispenseInkOnto(Surface)
a plus de sens pour moi quePen.getColor()
.Les getters 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 d' idiome Information Expert .
Les getters et les setters, cependant, sont des maux nécessaires à la frontière des couches - UI, persistance, etc. L'accès restreint aux éléments internes d'une classe, tels que le mot-clé friend de C ++, l'accès protégé par package Java, l'accès interne de .NET et le modèle de classe Friend peut vous aider à réduire la visibilité
getters
et les setters à ceux qui en ont besoin.la source
Cela dépend de la façon dont la propriété est utilisée. Par exemple, supposons que vous ayez 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.
Maintenant, disons que vous avez 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
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 les setters explicites. Voici pourquoi:la source
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 compte:
PHP:
puis de l'intérieur de l'objet lui-même:
PHP:
De cette façon, vous pouvez toujours utiliser ce premier argument pour autre chose (comme envoyer un indicateur pour savoir s'il faut ou non utiliser les données mises en cache ici peut-être).
la source
Je dois manquer le point ici, pourquoi utiliseriez-vous un getter dans 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
La manière puriste OO est d'éviter les deux et de suivre la loi de Déméter en utilisant l' approche Tell Don't Ask .
Au lieu d'obtenir la valeur de la propriété de l'objet, qui couple étroitement les deux classes, utilisez l'objet comme paramètre, par exemple
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.
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
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:
Cela doit être fait dans l'intérêt de maintenir la cohérence avec les accès effectués depuis l'extérieur de l'objet.
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, accéder directement au champ signifierait que vous manquez ce traitement supplémentaire, et votre programme pourrait mal tourner si ce traitement doit toujours être effectué pendant ces accès.
la source
Si vous voulez dire «la plupart de l'encapsulation» par «puriste», 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. Pour les autres classes, y compris les sous-classes, j'accède à l'état de l'instance en utilisant les getters.
la source
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
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 du design.
la source
Ç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
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 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
Si je ne modifie pas la propriété, j'utiliserai une méthode publique à
get_property()
moins que ce ne soit une occasion spéciale telle qu'un objet MySQLi à l'intérieur d'un autre objet, auquel cas je rendrai simplement la propriété publique et y ferai référence$obj->object_property
.À l'intérieur de l'objet, c'est toujours la propriété $ this-> pour moi.
la 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és (é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
J'aime la réponse de cmcculloh , mais il semble que la plus correcte soit la réponse de Greg Hurlman . Utilisez getter / setter tout le temps si vous avez commencé à les utiliser dès le départ et / ou si vous êtes habitué à travailler avec eux.
En passant, je trouve personnellement que l'utilisation de getter / setter rend le code plus facile à lire et à déboguer plus tard.
la source
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