(10-08-2014, 06:05 PM)srm a écrit : Je comprends pas très bien ce que tu expliques niahoo.
C'est pas parce que tu peux coder ton objet sale que tu dois le faire, c'est un peu comme la programmation fonctionnelle, tu peux l'utiliser n'importe comment, c'est pas pour ça que la programmation fontionnelle est nulle.
Ce que je dis c'est que les langages fonctionnels comme Haskell ou Erlang ont généralement tendance à pousser le développeur à faire de la programmation fonctionnelle. Alors que les langages comme PHP te fournissent tout un tas de bordel et tu as cinquante devs différents qui te proposent de structurer tes classes plutôt comme ceci ou comme cela. En FP bien sûr tu as plusieurs façons de faire mais comme le paradigme est simple on en revient toujours à Type-de-données-en-entrée/Type-de-données-en-sortie pour les fonctions, qui auront toujours une valeur de retour (à l'exception des fonctions qui ne retournent jamais); tandis que les envois de messages n'auront jamais de valeur de retour (en fait si, le message lui-même, vu que c'est une fonction qui envoie, mais ceci est un détail d'implémentation). Du coup quand tu implémentes un objet avec un getter tu envoies clairement un message question puis un message réponse. Je trouve donc que dans les langages FP que j'utilises les choses sont plus claires. En PHP on peut faire de l'objet, ou pas, du simili objet, mais en aucun cas l'implémentation ne t'incite à faire quelque chose de propre, vu qu'elle est juste pompée sur Java/C++ qui faisait la même chose des années auparavant.
Ici il ne faut pas te tromper, je parlais de PHP en tant qu'implémentation d'un langage OO. Je ne parle pas en soi des paradigmes OO et FP qui valent ce qu'ils valent et qui sont parfois complémentaires comme en Erlang.
(10-08-2014, 06:05 PM)srm a écrit : Et l'article East pousse justement le concept "tell don't ask" et donc "t'interdit" de travailler avec des méthodes privées de l'objet, donc c'est cool.
Qu'est-ce qu'une méthode privée ? Est-ce un objet qui s'envoie un message à lui même et qui le traite de suite ? Non, c'est une bête fonction qui agît (ou pas) sur le state de l'objet (une « méthode » donc) ou une fonction utilitaire qui n'intéresse que l'objet (une fonction tout court).
Ici aussi c'est le langage, PHP, qui t'interdit de travailler avec les private. Tell don't ask c'est bien mais je le redis : est-ce que chaque objet de ton système qui contient des données à afficher quelque part doit implémenter des putters ? Je trouve que le paradigme objet et surtout ses limites ne sont pas correctement définies par les langages qui les implémentent ; chaque semaine dans le monde de PHP on propose une nouvelle façon de faire de l'objet correctement.
Donc voilà c'est pour ça que pour mon code, j'assume faire plutot du procédural organisé en classes, et je crée mes classes par rapport aux données que j'utilise. Donc en gros des model, des collections, des vues, des controlleurs si c'est du web, et des « applications » ou managers qui ont en gros la responsabilité de ce qui doit être fait i.e. le code métier, en s'appuyant sur tout le reste.
Moi j'appelle ça de l'objet parce que c'est plus simple, mais ce sont des objets au sens PHP du terme, des instances de classes, on n'est pas dans le « vrai » (pour ce que ça veut dire) paradigme objet. Généralement ça convient à mes collègues.
(10-08-2014, 06:05 PM)srm a écrit : Je vois pas en quoi ton exemple est faux ou alors on ne doit pas faire ça.
Il est juste en tout point, si par exemple tu avais un système d'encapsulation d'objet (par exemple tag et tag parent) ça peut être du code cohérent et en plus qui marche comme prévu.
Ce qui me gène dans mon exemple, c'est que
$a1
peut accéder au membre privé v
de l'objet $a2
dans la méthode foo
sous prétexte qu'il est de la même classe. Si j'implémente un système d'humain, est-ce que niahoo peut accéder au cerveau d'oxman et savoir pourquoi il a changé de pseudo sans le lui demander via une méthode publique ? Non. Du coup, ma compréhension du paradigme objet conçoit bien l'isolation entre objets de type Humain
alors que PHP lui propose au développeur d'outrepasser cette isolation. Est-ce juste ou faux ? je ne sais pas, mais ça ne me semble pas très malin en tout cas. Parce que le développeur qui voudra faire de l'objet mais qui n'est pas sur de faire du « bon » objet aura cette possibilité alors que je crois perso qu'il ne devrait pas. ça renifle le futur bug bien pérave à plein nez. Du moins à mon humble avis, je ne suis ni un expert ni un fan de l'OO donc je peux tutafé me tromper.De la même manière,
$b
accède à $a2->v
alors qu'il est private et non protected. Bon, ici ça ferait planter $b->foo
donc c'est plus simple comme ça. Est-ce un choix judicieux ou bien faudrait-il être plus strict ? Moi ça me convient comme ça. Mais du coup on en revient au problème de mon paragraphe précédent qui, là, ne me convient pas du tout. Et pourtant je me rappelle plusieurs fois avoir implémenté des méthodes statiques qui utilisaient les privates des objets de la classe. C'etait beaucoup plus simple donc je l'ai fait, mais j'ai quand même testé avant car cela n'allait pas de soi pou moi que cela fonctionne ; et ensuite j'ai pas mal hésité car ça ne me paraissait pas propre.(10-08-2014, 06:05 PM)srm a écrit : Et vu que justement on dit tous dans ce topic (si j'ai bien suivis) qu'utiliser les propriétés privés avec des getter c'est mal, pourquoi alors vous pensez (si j'ai bien suivis) que la méthode East c'est trop overkill ?
Et bien, du coup si on considère qu'on envoie un message, utiliser un getter qui ne fait que renvoyer la valeur me semble approprié. En Erlang par exemple tu n'as pas le choix. Mais souvent on trouve des objets (y compris dans le code de Laravel que je prend comme modèle de qualité) qui ne sont là que pour représenter des données, et dans ce cas on mets les propriétés publiques car c'est plus simple. Mais c'est moins solide. Le getter te donne du contrôle parce qu'il permet d'avoir un membre privé mais tout de même lisible, donc je ne dirais pas que c'est mal, par contre à la lecture ça fait quand même un peu boulet si au final on a implémenté le setter et qu'il ne fait rien de spécial non plus.
Pour le côté overkill, je trouve qu'un système de log devrait se baser sur un putter qui reçoit en paramètre un flux, ça me paraît très intelligent, et on peut le voir dans le code de Monolog ou de Symfony sur le composant console (voir posts précédents). Sur un système de gestion de compte bancaire
putBalance(Stream s)
me paraît pas si utile car ton solde sera toujours affiché avec du formatage. Par exemple sur une page web, je vois mal Symfony commencer à faire un output du HTML, puis appeler putBalance
puis finir le HTML. Hmm... à moins de passer une closure mais déjà ça sera relou à faire je crois, et en plus ça peut amener à un style totalement basé sur CPS (Continuation Passing Style) (voir les commentaires de l'article et voir plus loin).Ensuite, Arnadus l'a bien fait remarquer, pour les autres exemples de l'article on multiplie les classes inutilement, ce qui donne un code virtuellement magnifique au niveau de l'abstraction mais chiant à lire et long. Plus de lignes, plus de bugs. Je ne fais que paraphraser ce qu'on a déjà dit donc je ne m'étends pas sur ce point.
On dirait des fois que les mecs qui sont à fond dans l'OO "y croivent" que l'abstraction se fait uniquement en objet. L'abstraction c'est comme une drogue. C'est très sympa et très fun mais l'overdose arrive vite et ton code, comme après avoir fumé un très gros joint, ne fait plus grand chose. Mis à part peut-être décorer les colonnes d'un blog de développeur. Et j'ai l'impression que les plus gros drogués à cette came sont les fans d'OO. Pour moi l'abstraction réside plutot dans les types de données réelles, qu'il faut bien délimiter, sur lesquels on va créér nos types en FP ou nos classes en OO. Elle ne réside pas dans le fait d'ajouter plus de classes. Bon là c'est un avis/goût plus perso peut-être.
Mon post est un peu long, je rentre de ouikande j'ai pas grand chose à glander, j'espère que vous aussi. Sinon désolé.
Ah, et j'ai failli oublier, il faut que j'en rajoute une louche. Le CPS. Le CPS c'est parfois très utile voir indispensable, par exemple pour implémenter les monades en Haskell ou Erlang. On met quelques lignes de codes, on tell un objet de faire quelque chose et on lui passe aussi une callback. Donc voilà, c'est pratique, mais ça reste relativement peut utile. Sauf ... sauf en Javascript, ou les mecs qui ont défini ce langage n'étaient pas assez éveillés pour implémenter
sleep
; ironie du sort. Du coup en Javascript et notament sur Node on a du CPS partout partout, parfois masqué comme sont masqué les envois de messages sur Erlang/OTP. Mais là en matière d'OO c'est bizzare. J'envoie à un objet un message, sans retour, mais du coup j'implémente le reste de ma méthode dans une callback que cet objet va à son tour appeler. Sauf que dans la callback c'est mon propre état (à moi l'appelant), potentiellement private, qui sera généralement décrit. Et ça je trouve ça moyen voire crados. Mais c'est parfois indispensable et tout à fait correct du point de vue du langage.Donc pour conclure : L'objet, très bien, East, super ! mais il faut aussi savoir rester simple, aller droit au but et passer à autre chose, et je trouve que l'auteur ne montre pas ça. Oui tout ça pour ça, mon post n'est pas l'exact exemple de ce que je raconte
![Smile Smile](https://jeuweb.org/images/smilies/smile.png)
Et puis surtout, au lieu de faire de l'abstraction dans tous les sens, ils pourraient pas faire évoluer leur langage pour éviter ce genre de verbiage :
Code :
return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
hein ?
Héhé, pas fini, je trouve aussi sa définition du Nord et du Sud pas très convaicantes en regardant au hasard quelques classes de mon code, pas vous ?