Billet très intéressant et très bien écrit, mais je reste également non convaincu. Je qualifierai complètement ceci d’optimisation prématurée, car je pense que comparer deux mains de poker ne consomme quasiment rien en ressources, même pour une grande plate-forme de poker, et de toute façon on pourrait facilement scaler à l'horizontale. Mais je comprends qu'il s'agit plus d'un exemple que d'un cas réel, donc je ne m'attacherai pas trop sur cet aspect là, même si pour moi il est valable dans 99% des cas. En fait ce que tu proposes, c'est de lier le format des données aux traitements qui seront fait dessus, pour simplifier les traitements. C'est ce qui se faisait au début de l'informatique, et je pense qu'on en est revenu pour de bonnes raisons, En dehors d'un véritable besoin de performance, voici les limitations de cette solution : - Il est difficile à comprendre. Même avec des commentaires, un modèle compliqué abouti à un code complexe à appréhender, ce qui abouti à des bugs. Je suis un nouveau programmeur sur ton projet, et je me sers de ta classe pour afficher la main, si j'utilise _cartes, je ne me rendrai compte du problème que lorsque j'aurais une suite ou une couleur. C'est fourbe. Et en cas de bug à trouver, c'est très délicat de s'assurer que le problème viens (ou non) d'ici. - Il ne représente pas le réel, et cela à des conséquences sur la ré utilisabilité. Je risque d'avoir du mal à réutiliser cet algorithme sur d'autres variantes de poker par exemple. Imagine que je rajoute un joker. Imagine que je joue au Omaha, où ma main à 7 cartes? Comment vas-tu tordre ton modèle? Quels tests proposeras-tu me convaincre qu'il ne présente pas de bugs? Certes, 18 fonctions de comparaison, c'est peut-être pas le plus efficace. Mais je suis sûr que le code est correct au premier coup d’œil, que mon nouveau stagiaire va parfaitement comprendre comment traduire la demande de l'expert en code sans tout casser, et qu'il pourra s'en resservir pour le traitement suivant à faire, et ça pour moi, ça n'a pas de prix, et c'est ce qui fait la valeur de l'objet. Au plaisir de te lire.
Bonjour François, je te trouve un peu dur avec les "certains [qui] qualifieraient [ça] d’optimisation prématurée". Mais je te comprends, car en réalité, les logiciels qui ont vraiment besoin d'une réelle optimisation sont assez rares, donc peu de développeurs savent de quoi ils parlent lorsqu'ils parlent d'optimisation. De plus, la mode des langages objet dits de haut niveau (java, C#), qui ne permettent pas une gestion fine de la mémoire, fait que beaucoup de développeurs n'ont aucune idée de ce qu'il a "sous le capot", et pour eux, l'optimisation consiste juste à limiter le nombre d'indirection. Mais en fait, l'optimisation ce n'est pas ça. L'optimisation est une tâche complexe, qui consiste en deux étapes. La première, et la plus importante, consiste à détecter quels sont les morceaux de code qu'il faut optimiser. La deuxième consiste à reprogrammer ces morceaux de code, souvent en abandonnant les paradigmes, patrons et principes qui permettent une meilleure modularité (objet, généricité, patterns, idiomes, etc.). Et c'est en ce sens qu'il faut comprendre la problématique de "l'optimisation prématurée". Car dans la majorité des cas, le simple respect des règles élémentaires permet d'obtenir les performances suffisantes pour le logiciel que l'on est en train de fabriquer. Donc, dans la majorité des cas, on préfère avoir un logiciel un poil moins rapide, mais plus facile à maintenir. Il s'agit d'un problème de coût. Car l'optimisation et la maintenance ont un prix. J'ai donc l'impression que tu mélanges deux choses. D'une part, l'imitation du réel, et d'autre part l'optimisation. -> Pour l'imitation du réel, je suis entièrement d'accord avec toi. Mais je crois aussi que notre cerveau fonctionne ainsi, essentiellement par mimétisme (on reproduit ce que l'on voit), et que donc cet écueil est normal chez un jeune développeur. Et qu'il doit se corriger avec le temps. Sur ce point d'ailleurs, on retombe assez vite sur le problème de l'abstraction. Par exemple, si à la place d'une classe Jeu, qui contient les données de la partie en cours, on a une classe Modèle (référence au MVC), alors on se place à un niveau d'abstraction supplémentaire. Se pose alors le problème d'évaluer le rapport avantage/inconvénient de ce saut d'abstraction. C'est intéressant, mais c'est un autre débat. -> L'optimisation, quant à elle, est indépendant de l'architecture. Optimiser un logiciel ne consiste pas à prévoir à l'avance une architecture qui sera plus efficace: ça c'est ce qu'on appelle le génie logiciel (je préfère l'anglais: software engineering). Je te propose un exemple: l'addition de matrices. On voit dans cet exemple qu'on peut décider, dès la phase de conception, quel type d'architecture on va choisir. Si on estime à priori (avant de commence le dev), qu'il est important de pouvoir additionner rapidement plusieurs matrices, alors on choisira la version avec les opérateurs "templatisés" et à l'extérieur de la classe Matrix. Sinon on fera un simple conteneur "STL-like", qui contient lui-même ses opérateurs. Mais ce choix est un choix de conception, ce n'est pas de l'optimisation. La conception est à priori, l'optimisation est à posteriori. Donc dans ton exemple de jeu d'échec, en fait tu parles de conception, pas d'optimisation.
Un billet agréable à lire mais qui peine un peu à convaincre... Je trouve que la démonstration est bien faite mais que la conclusion qu'il faut en tirer est une autre! Si je suis bien le raisonnement: 1. la modélisation naïve du réel conduit à l'échec (contrairement à ce que les exemples sempiternels de formes et de voitures dans les livres d'initiation laissent croire); 2. la modélisation est en fait un travail itératif; 3. le travail de modélisation doit donc être éclairé par le souci d'utiliser des algorithmes plus généraux et plus puissants; Conclusion: ce qui justifie la POO est qu'elle permet de faire ce travail à l'abri grâce à l'encapsulation des données En fait, si on examine le cas pratique, on se rend compte que le résultat final est la déconstruction du problème en un petit nombre de fonctions primitives et orthogonales, donc le résultat d'une analyse fonctionnelle du problème, pas d'une analyse objet! Un plus pour les langages fonctionnels, un moins pour les langages OO. Quant à l'encapsulation, elle n'est d'une part pas nécessaire à la programmation objet (cf Python ou CLOS) et possible par module dans des langages non-objets, comme Haskell par exemple.
Merci pour ce billet, très utile
Envoyé par kolodz Note : Pense à utiliser le = nom du langage quand tu utilise la balise code. Les blogs n'ont pas de coloration syntaxique par défaut. On ne sait pas d'avance si tu parle de Java ou de C# ou du Cobol ! Fait, merci du tuyau (sur le fil politique, j'emploie assez peu la balise CODE...)
Tu t'es allié avec bouye pour le sujet des cartes ? Il est quand votre jeu de pocker ? Cordialement, Patrick Kolodziejczyk. Note : Pense à utiliser le = nom du langage quand tu utilise la balise code. Les blogs n'ont pas de coloration syntaxique par défaut. On ne sait pas d'avance si tu parle de Java ou de C# ou du Cobol !
Trés trés interressant
Une fois par semaine sera un trés bon rythme, vas-y amuse-toi je me suis abonné !
J'adore le titre "Réac' programming" C'est du jamais vu, ca c'est du vrai contenu original.
Merci pour ce billet très intéréssant