Bonjour à tous
Je programme depuis quelques temps dans plusieurs langages tels que le Python, le JS et plus récemment je me suis remis au C#. Et une chose qui m'avait vraiment fait stagner à l'époque où j'avais appris le C# pour la premiere fois c'est que je comprenais pas vraiment la POO.
Aujourd'hui je comprend les concepts de base, l'héritage, le polymorphisme et l'encapsulation mais j'ai du toujours du mal à comprendre comment utiliser la POO. Je sais à quoi ca sert, je sais quels avantages ca peut apporter à un programme mais j'arrive pas à me projeter et à la mettre en pratique.
Par exemple, la plupart des tutos de programmations abordent les concepts rudimentaires avec des exemples insipides tels que :
On créé une classe Vehicule qui permet de créer une sous classe Voiture ou une sous classe Camion qui permettront de créer un objet voiture1 ou camion1...
On créé une classe Personne dont héritera une classe Programmeur ou une classe Etudiant...
Tous ces exemples c'est super pour comprendre l'héritage par exemple mais en ce qui concerne la programmation de véritables logiciels je suis pas plus avancé vous voyez ?
J'ai des idées de projets de programmes mais je suis pas plus avancé sur la question de savoir comment organiser mon code en classes et comment ces classes doivent intéragir entre elles.
Admettont que je veuille faire un programme de traitement de texte par exemple, qui permet d'ouvrir un fichier, y'ecrire du texte, sauvegarder, faire des undo, redo, rechercher du texte... Comment transcrire mes idées en classes utilisant la POO ? Sur quoi je dois me baser pour créer mes classes ?
Est-ce que j'aurais au moins besoin d'utiliser la POO dans ce genre de cas ? Comment sait-on si on en besoin et est-ce vraiment nécessaire sur des petits programmes ? J'ai déjà vu un script minuscule en Python (pour télécharger des images depuis le web) qui utilisait des classes et je trouvais ca bizzare comme idée.
Je pense que c'est des questions qui relèvent de la conception et du design mais je n'arrive pas à trouver de bonnes sources de réponses donc je fais appel à vous, si vous connaissez de bons tutos ou des bouquins car jusque là tous les tutos que j'ai pu suivre c'est en gros on t'apprend à représenter des objets de la vie réelle et ensuite "Démerdes toi"
Bref ca fait beaucoup de questions, ne vous sentez pas obligé de répondre à tout mais j'apprécierais grandement votre aide !
Interesse toi aux design patterns ; ce sont des relations entres classes qui remplissent un role specifique pour solutionner de maniere elegante un probleme donne.
https://en.wikipedia.org/wiki/Design_Patterns
Chaque design pattern est relativement petit en soi, et repond a un besoin atomique ; pour implementer des fonctionnalites, et creer des programmes entiers, on en agence un grand nombre entre eux.
Au passage, l'exemple des "vehicules" ou celui des "animaux" est a proscrire absolument pour expliquer l'heritage ; meme si ca permet de visualiser certains concepts de POO.
Si on a une interface Vehicule, et deux specialisations Voiture et Moto, ou est-ce qu'on met un Trike, hybride entre les deux ? Si on a Avion et Bateau, ou est-ce qu'on met un Hydravion ?
Si on a une interface Animal, et deux specialisations Mammifere et Ovipare, ou est-ce qu'on met un ornithorinque ? ...
Il n'y a a pas de solutions elegantes a ces problemes de conceptions en se basant sur une hierachie d'heritage de classes (plus de specialisations ? mais absence de factorisation ? etc.), et ces exemples devraient surtout servir a montrer l'utilite de la conception par composition, avec des archi type ECS Entity-Component-System
Merci beaucoup pour cette piste et désolé de la réponse en retard, j'ai trouvé quelques bouquins sur kindle traitant du sujet
Je trouve ce post très pertinent.
Souvent lorsqu'on parle de POO, ce qu'on met en avant c'est l'héritage, le polymorphisme et la surcharge. Et souvent, comme l'OP l'a bien remarqué (bravo à lui), ce sont des exemples triviaux qui ont peu de sens.
Cela fait 13 ans que je programme professionnellement, et l'héritage franchement, moins j'en vois, mieux je me porte. Pour moi, le matraquage scolaire pousse les gens à user et abuser de l'héritage et des classes abstraites là où en réalité, on a simplement besoin d'une interface.
La POO c'est un moyen. Or les gens qui enseignent la POO, ils en font une fin et c'est très dommageable. J'ai vu nombre de scénarios où on essayait de partager des morceaux de fonctionnalités entre plusieurs classes au moyen de l'héritage, et généralement on obtenait des choses moins maintenables et moins lisibles que si on avait copier coller les 2 ou 3 membres privés qu'on voulait effectivement factoriser.
_skip +1million
Le 30 août 2016 à 16:41:13 whiteapplex a écrit :
Mais les concepts liéés à la POO, au fond, ne sont que des lignes de conduites.
La seule chose inattaquable du post.
Pour le reste je passe, mais le document qui sait se sauvegarder tout seul, comme la lettre qui se poste elle-même, ça je trouve que c'est un mauvais conseil.
Pour le reste je passe, mais le document qui sait se sauvegarder tout seul, comme la lettre qui se poste elle-même, ça je trouve que c'est un mauvais conseil.
Je trouve que ça dépend comment tu vois les choses, est-ce que ta classe représente le document en lui-même ou elle représente plutôt un objet qui contient le document (un gestionnaire de document mais qui gère qu'un document à la fois) ? Si c'est la deuxième possibilité j'pense pas qu'avoir une méthode pour charger / sauvegarder le document soit vraiment dérangeant d'un point de vue logique de conception.
Le 30 août 2016 à 20:03:41 LEpigeon-888 a écrit :
Pour le reste je passe, mais le document qui sait se sauvegarder tout seul, comme la lettre qui se poste elle-même, ça je trouve que c'est un mauvais conseil.
Je trouve que ça dépend comment tu vois les choses, est-ce que ta classe représente le document en lui-même ou elle représente plutôt un objet qui contient le document (un gestionnaire de document mais qui gère qu'un document à la fois) ? Si c'est la deuxième possibilité j'pense pas qu'avoir une méthode pour charger / sauvegarder le document soit vraiment dérangeant d'un point de vue logique de conception.
Le chargement et la persistence, c'est plus le rôle d'un service à mon sens. C'est clair que tu peux balancer du code de gestion de fichier dans le document, avec les charsets, les codecs, les buffers où je ne sais quoi. Si tu rajoutes les fonctionnalités SaveAs, Save Copy, Reload... Au bout d'un moment tu sens que tu sors du scope de ton document, tu sens que c'est externe puis que ça devient très "fat" et que tu multiplies les dépendances.
A côté de ça, tu peux dégager tout ça dans un service et découpler ce qui est édition de document (contenu, état, insertion etc...). Et avoir une classe de pilotage entre deux qui réagit aux interactions utilisateur avec la barre d'outil, gère la manipulation des documents en se servant du service, etc...
T'obtiens un code clean, avec des classes qui ont un scope et des responsabilités bien définies, et c'est tout bénéf. L'erreur du concept "rapprocher les données et les traitements" inhérent à la POO, c'est de voir 10x trop large, soit au lieu de considérer la photo, y ajouter le cadre, le mur, le clou, et l'immeuble dans lequel elle est.
Vois d'abord ce qu'est un data type puis un abstract data type (ADT), puis un objet, puis compare ADT avec Objet pour comprendre les avantages et désavantages de ces deux techniques d'abstraction de données (et d’implémentations pour l'objet). Les classes ne sont qu'un moyen de faire de l'objet parmi d'autres (prototypes, messages, higher-order programming, ...).
Oui je vois ce que tu veux dire, mais perso j'suis pas fan de faire des classes presque vide, si mon document est juste représenté par un nom et un contenu, et que les seuls méthodes dont j'ai besoin sont de le sauvegarder et de le charger, je préfère avoir tout dans la même classe que de créer deux petites classes, quitte à séparer les deux classes plus tard si je dois ajouter beaucoup de trucs (c'pas bien long à faire, juste un ou deux copier/coller).
Après je conçoit que c'est possiblement pas une bonne pratique.
La POO c'est pratique pour représenter les acteurs de ton programme.
Si tu veux faire un Asteroid, tu peux envisager facilement une classe Vaisseau, une classe Asteroid, une classe Tir.
Si plusieurs de tes acteurs partagent les même fonctionnalités, tu peux envisager de les "grouper" pour ne pas avoir le même code à écrire X fois (héritage). Par exemple, les 3 classes ci-dessus pourraient partager les fonctionnalités nécessaire pour se déplacer à l'écran et gérer des collisions.
Là où la POO devient chiante c'est pour faire interagir tes acteurs, parfois c'est prise de tête et ton code devient inutilement complexe (possible solution: design pattern)
Le 31 août 2016 à 16:20:37 dark_drow a écrit :
La POO c'est pratique pour représenter les acteurs de ton programme.
Si tu veux faire un Asteroid, tu peux envisager facilement une classe Vaisseau, une classe Asteroid, une classe Tir.Si plusieurs de tes acteurs partagent les même fonctionnalités, tu peux envisager de les "grouper" pour ne pas avoir le même code à écrire X fois (héritage). Par exemple, les 3 classes ci-dessus pourraient partager les fonctionnalités nécessaire pour se déplacer à l'écran et gérer des collisions.
Imagine tout ce que le vaisseau a besoin d'avoir comme références pour gérer ça lui-même.
La POO c'est pratique pour représenter les acteurs de ton programme.
Perso j'aurais tendance a recommander une approche differente ; toutes les entites d'un programme se modelisent generalement tres tres bien avec un ECS, car il suffit de "composer" les features dont a besoin un acteur. On utilise alors les Systems pour toute la logique travaillant sur une ou plusieurs entites (collisions, affichage, etc.). Le tout dans une arborescence relativement plate et donc tres modulaire et souple.
On se contente d'utiliser l'heritage pour le framework, et les qq classes utilisateurs qui ont besoin d'heriter pour le polymorphisme (CollisionSystem <> System, PhysicsComponent <> Component, etc.)