Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#76 Le 05/02/2012, à 11:17

Morgiver

Re : Discussion autour du concept de la POO

J'ai très bien compris. J'avoue que les getter en private ça le fait pas.
Pour cette classe config, d'accord, beaucoup de truc inutiles. Je vais changer ça.
J'ai fait cette classe config avant les autres. Je crois que je me suis un peu embrouillé sur la différence entre l'utilisation des getter pour l'extérieur des classes et l'intérieur.

Mais prenons les autres classe, les getter et setter sont utilisés comme il faut, non ?!

Hors ligne

#77 Le 05/02/2012, à 11:58

Haleth

Re : Discussion autour du concept de la POO

Mouais, c'est comme ca, mais la encore, il te faut du traitement pour que ce soit utile (ou alors, c'est un object à vocation evolutive, tout depend de l'object ...)


Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#78 Le 05/02/2012, à 12:08

Morgiver

Re : Discussion autour du concept de la POO

Ha oui en effet, ça doit évoluer vu que c'est un exemple.
Pour un forum par exemple, c'est obligatoire de vérifier les données via les setter/getter.

Hors ligne

#79 Le 06/02/2012, à 10:52

Mathieu147

Re : Discussion autour du concept de la POO

Morgiver a écrit :

Si j'ai bien compris le DAO c'est a peu près ça oui, enfin, je pense. C'est en effet une classe pour charger ou transmettre des données. Les différentes fonctions doivent pouvoir contrôler les entrées et sorties.

Haleth a écrit :

Tu sais à quoi servent tes getter/setter ?
A rien.
Rien du tout, si ce n'est te prendre du temps, des lignes, et rajouter des la complexité.

Aucun bénéfice.
Les ravages de la POO..

Ça dépend toujours de comment tu vas utiliser ta classe.

Prenons par exemple le cas des DAO. Tu peux faire une classe Dao qui représente un objet d'accès aux données (qui peut éventuellement être abstraite, ça serait pas plus mal). Là dedans, tu as des getter et des setters même pour les choses qui semblent simples (retourner la valeur d'un champ par exemple, comme Morgiver l'a fait ci-dessus).

Ensuite, tu décides que certains objets seront stockés dans une base de données. Là, tu fais une classe MysqlDao qui hérite de Dao, et donc de tous les setters et getters. Puisque la classe est spécialisée dans les bases de données, il va falloir faire des requêtes SQL, et certains getters et/ou setters pourraient bien se retrouver un peu complexifiés.

Maintenant, quand tu dois stocker un objet en base de données (prenons comme exemple que tu dois enregistrer une personne), tu fais une classe PersonDao qui hérite de MysqlDao, et tu redéfinis seulement quelques méthodes supplémentaires dont tu aurais besoin.

Après, tu peux vouloir que certaines choses soient stockées dans des fichiers XML. Tu n'as qu'à faire une classe XmlDao qui hérite de Dao, puis une classe TrucDao qui hérite de XmlDao et qui enregistre des trucs dans un fichier XML.

À partir de là, tu pourras tout à fait faire des choses comme

$personne = new PersonDao('Jean', '25');
$personne->setAddress('Rue des trucs bidules n°42, 75000 Paris');
$personne->save();

$truc = new TrucDao();
$truc->setBidule(array(1,2,3), 'Bla bla');
$truc->calcule();
$truc->save();

$autrePersonne = PersonDao::get('Albert');
$autreTruc = TrucDao::get(36);
$autrePersonne->setTrucName($autreTruc->getName());
$autrePersonne->update();

et là, tu auras créé un enregistrement en base de données pour une personne et un fichier XML qui représente un truc; puis tu auras été chercher un enregistrement de personne existant, ainsi qu'un truc existant, et tu auras mis à jour la deuxième personne. Et tout ceci, sans même savoir si tu utilisais une base de données, un fichier XML, ou n'importe quoi d'autre!


Un autre avantage des getters et setters, c'est que si tu n'es pas certain de devoir faire des vérifications, tu peux toujours mettre des getters/setters, et si jamais ils restent à tout jamais de simples retours de champs, ce n'est pas grave. Par contre, le jour où tu décideras d'ajouter des vérifications, tu ne devras pas changer ton code pour qu'il utilise les getters et setters au lieu des champs directement.


Il y a dans Delphi (ou dans Pascal, je ne sais pas trop) les propriétés. C'est un bon compromis entre l'utilisation des champs et les getter/setters. Quand tu as une classe Class, tu définis une propriété Property, et dans la classe, tu définis les getters et setters. Ensuite, à l'extérieur de la classe, tu utilises comme ça:

$classe = new Class();
$classe->property = 'Bla bla';

(je ne me rapelle pas de la syntaxe exacte de Delphi alors j'ai utilisé la syntaxe PHP)
Ainsi, quand tu utilises la propriété Property, en fait c'est le setter qui est appelé, sans que l'utilisateur de la classe ne sache si c'est un simple champ ou une fonction plus complexe.

Ceci dit, c'est uniquement du sucre syntaxique, et je trouve que ça n'apporte fondamentalement pas grand chose.


Pour terminer, pour ce qui est des getters et setters private, l'intérêt est assez limité pour un simple champ. Si un jour tu dois utiliser un getter, ça ira assez vite de changer le code de ta classe (ce qui n'est pas nécessairement le cas pour les variables publiques qui doivent être transformées en getter/setter).


Pffff…

Hors ligne

#80 Le 10/02/2012, à 17:31

Luc Hermitte

Re : Discussion autour du concept de la POO

Les setters sont généralement des ruptures d'encapsulation. Même avec vérification, ils sont signe d'une réflexion en termes de données et non de services rendus.
Hop, de la lecture (mode fainéant, désolé -- j'avais pas posté des liens à ce sujet dans ce fil déjà ? Ah si, message 38) :
- http://www.siteduzero.com/forum-83-4119 … l#r3810730
- http://blog.emmanueldeloget.com/index.p … accesseurs
- http://blog.emmanueldeloget.com/index.p … de-demeter
- http://www.javaworld.com/javaworld/jw-0 … olbox.html
- http://stackoverflow.com/questions/5650 … tters-evil
- http://www.idinews.com/quasiClass.pdf (pas sûr que le lien marche encore ...)

Dernière modification par Luc Hermitte (Le 10/02/2012, à 17:32)

Hors ligne

#81 Le 14/02/2012, à 10:38

Mathieu147

Re : Discussion autour du concept de la POO

Luc Hermitte a écrit :

Les setters sont généralement des ruptures d'encapsulation. Même avec vérification, ils sont signe d'une réflexion en termes de données et non de services rendus.
Hop, de la lecture (mode fainéant, désolé -- j'avais pas posté des liens à ce sujet dans ce fil déjà ? Ah si, message 38) :
- http://www.siteduzero.com/forum-83-4119 … l#r3810730
- http://blog.emmanueldeloget.com/index.p … accesseurs
- http://blog.emmanueldeloget.com/index.p … de-demeter
- http://www.javaworld.com/javaworld/jw-0 … olbox.html
- http://stackoverflow.com/questions/5650 … tters-evil
- http://www.idinews.com/quasiClass.pdf (pas sûr que le lien marche encore ...)

Je crois que, comme tout (et en particulier les Singletons dont on a parlé dans ce sujet un peu avant), les getters et setters ne sont pas intrinsèquement bons ou mauvais, ils représentent un choix à faire ou non en fonction du résultat que l'on veut obtenir et des contraintes de programmation que l'on se met.

Je pense que c'est justifié de mettre un champ public accessible directement si le champ en question représente une propriété n'ayant pas d'interaction directe avec le reste de l'objet et son contexte (autre objets qu'il utilise ou qui l'utilisent). Mais je trouve que de manière générale c'est très difficile de le déterminer. Comment être certain que le changement d'une propriété n'affectera rien d'autre?

Par exemple, si je fais un objet qui représente le personnage d'un jeu, et que son nombre de points de vie est un champ public: si je fais $personnage->pointsDeVie = 0, alors il faut aussi peut-être lancer plusieurs autres méthodes pour (par exemple) vérifier qui a gagné puisqu'un personnage est mort. Si j'utilise un setter, je peux faire cette vérification. Sinon, c'est peut-être plus difficile.

Là où Emmanuel Deloget met le doigt sur un problème (tu vois, j'ai lu tes liens wink), c'est que le terme «setter» est trop générique. Quand on utilise setPointsDeVie(), on s'attend à ce que ça ne modifie que le nombre de points de vie. Or, ça peut enclencher tout un processus (est-ce que je suis mort? Est-ce que j'ai gagné?). Il faut plutôt faire plusieurs méthodes telles que damage(), heal(), kill(), etc. Ça revient au même, mais c'est beaucoup plus clair.

L'exemple que Emmanuel Deloget utilisait, c'est la fonction setSize() qu'on utiliserait sur un objet représentant une forme géométrique. Si on l'appelle comme ça, on peut penser que ça ne fait que changer la valeur de son champ size (alors qu'il vaudrait mieux lire la doc que faire de telles suppositions). Par contre, si on appelle la méthode resize() alors là on ne se contente pas d'assigner une variable, mais on se rend compte qu'on enclenche tout un processus de redimensionnement qui peut potentiellement avoir des conséquences sur tout un tas de choses, comme le recalcul d'une texture, le déplacement d'autres formes qui se trouvent aux alentours, etc.

Finalement, je crois que lorsque l'on utilise des setters et getters, ça gêne certains plutôt sur une question de nomenclature.


Pffff…

Hors ligne

#82 Le 14/02/2012, à 12:24

yohann

Re : Discussion autour du concept de la POO

Mathieu a écrit :

Par exemple, si je fais un objet qui représente le personnage d'un jeu, et que son nombre de points de vie est un champ public: si je fais $personnage->pointsDeVie = 0, alors il faut aussi peut-être lancer plusieurs autres méthodes pour (par exemple) vérifier qui a gagné puisqu'un personnage est mort. Si j'utilise un setter, je peux faire cette vérification. Sinon, c'est peut-être plus difficile.

Là où Emmanuel Deloget met le doigt sur un problème (tu vois, j'ai lu tes liens wink), c'est que le terme «setter» est trop générique. Quand on utilise setPointsDeVie(), on s'attend à ce que ça ne modifie que le nombre de points de vie. Or, ça peut enclencher tout un processus (est-ce que je suis mort? Est-ce que j'ai gagné?). Il faut plutôt faire plusieurs méthodes telles que damage(), heal(), kill(), etc. Ça revient au même, mais c'est beaucoup plus clair.

ben en fait c'est là que tu met le doigt sur le concept clé de la POO et de pourquoi les getter/setter c'est mal:
personnage->setPV(10) == setter == MAL
personnage->dammage(5) == utilisation d'une méthode approprié == BIEN

dans le premier cas les classe qui vont utiliser la méthode setPV seront bcp trop fortement couplées avec l'objet personnage (elle devront par exemple avoir conscience du nombre de pv du perso, de son armure, de s'il a ou pas pris une popo d'invincibilité)

dans le deuxième cas la méthode se contente de dire au perso "t'as pris 10 dégâts", celui-ci va ensuite mettre a jour ses PV comme un grand en fonction des paramètres cité précédemment) => couplage faible

donc à la limite un setter privé pour ne pas avoir a faire le check de mort a chaque fois que le personnage s'enlève lui même des PV, mais surtout pas de setter public

Dernière modification par yohann (Le 14/02/2012, à 15:05)


j.vachez, le génie du net | Soirées jeux sur Lyon | 441
++++++++++[>+++++++>++++++++++>+++<<<-]>++.>+.+++++++
..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.

Hors ligne

#83 Le 14/02/2012, à 14:50

Luc Hermitte

Re : Discussion autour du concept de la POO

On a effectivement un problème de nomenclature : un truc sensé faire set mais qui fait bien plus -- on retrouve l'article d'Emmanuel Deloget.
Mais ce qui me gêne le plus dans l'exemple du jdr, c'est le problème de responsabilité. Si tu exposes les PV, la responsabilité est déportée à l'extérieur. Ma vision est plus proche de celle qu'a détaillée Yohann. J'ai d'ailleurs un exemple à ce sujet, qui raffine encore un chouilla ce qu'il explique.
-> http://www.siteduzero.com/forum-83-6896 … l#r6675973

Ailleurs que je dis pas que l'approche variable en public me gêne.
Des setters ? Plus j'y pense, plus c'est un conception-smell pour moi. À la limite quand j'ai des invariants qui s'expriment sur plusieurs données, où quand changer une donnée sans l'autre n'a pas de sens (typiquement -> numérateur & dénominateur sur des nombres rationnels) j'offre des mutateurs qui altèrent l'état qui s'implémente à partir de plusieurs attributs.

Hors ligne

#84 Le 15/02/2012, à 09:49

Mathieu147

Re : Discussion autour du concept de la POO

yohann a écrit :

fortement couplées

Ah ouais, voilà, c'est ça le terme que j'avais sur le bout de la langue et que je ne trouvais pas quand je disais «interaction directe avec le reste de l'objet et son contexte».

Luc Hermitte a écrit :

On a effectivement un problème de nomenclature : un truc sensé faire set mais qui fait bien plus -- on retrouve l'article d'Emmanuel Deloget.
Mais ce qui me gêne le plus dans l'exemple du jdr, c'est le problème de responsabilité. Si tu exposes les PV, la responsabilité est déportée à l'extérieur. Ma vision est plus proche de celle qu'a détaillée Yohann. J'ai d'ailleurs un exemple à ce sujet, qui raffine encore un chouilla ce qu'il explique.
-> http://www.siteduzero.com/forum-83-6896 … l#r6675973

Je vois que tu as un exemple bien complet qui correspond à ce que je disais.

Luc Hermitte a écrit :

Ailleurs que je dis pas que l'approche variable en public me gêne.
Des setters ? Plus j'y pense, plus c'est un conception-smell pour moi.

Je ne suis toujours pas convaincu que ça soit mauvais. C'est mauvais quand le nom de la fonction est incorrect (setSize() ↔ resize()) ou quand le setter représente plus un effet (diminution des points de vie) que la cause de cet effet (damage(), heal(), kill()). Par contre quand il faut juste vérifier un truc, ça me paraît adapté.


Pffff…

Hors ligne