J'avoue, j'ai fait le péché de surutilisation, et même d'abus de l'héritage. Le premier projet de jeu (texte) que j'ai fait lorsque je suivais mon cours de POO allait jusqu'à "Porte verrouillée" et "Porte déverrouillée" de "Porte" et "Chambre avec une porte", "Chambre avec deux portes", et ainsi de suite de "Chambre".
Avec le jeu (graphique) sur lequel j'ai travaillé récemment, je pensais avoir appris ma leçon et limiter l'utilisation de l'héritage. Cependant, j'ai remarqué que les problèmes commençaient à apparaître. Ma classe racine commençait à gonfler de plus en plus, et mes classes de feuilles étaient pleines de codes en double.
Je pensais que je faisais toujours mal les choses, et après l'avoir consulté en ligne, j'ai découvert que je n'étais pas le seul à avoir ce problème. C'est ainsi que j'ai fini par découvrir les systèmes Entity après des recherches approfondies (lire: googlefu)
Quand j'ai commencé à le lire, j'ai pu voir à quel point il était capable de résoudre les problèmes que je rencontrais avec la hiérarchie OOP traditionnelle avec des composants. C'étaient cependant dans les premières lectures. Quand je suis tombé sur des approches ES plus «radicales», comme celle de T-machine .
J'ai commencé à être en désaccord avec les méthodes qu'ils utilisaient. Un système de composants purs semblait soit excessif, soit plutôt peu intuitif, ce qui est probablement la force de la POO. L'auteur va jusqu'à dire que le système ES est l'opposé de la POO, et bien qu'il puisse être utilisable le long de la POO, il ne devrait vraiment pas. Je ne dis pas que c'est faux, mais je ne me sentais pas comme une solution que j'aimerais mettre en œuvre.
Donc pour moi, et pour résoudre les problèmes que je rencontrais au début du billet, sans aller à l'encontre de mes intuitions, c'est toujours utiliser une hiérarchie, mais ce ne sera pas une hiérarchie monolithique comme celles que j'ai utilisées auparavant, mais plutôt un polylithique (je n'ai pas pu trouver un mot opposé à monolithique), qui se compose de plusieurs arbres plus petits.
L'exemple suivant montre ce que je veux dire (il est inspiré d'un exemple que j'ai trouvé dans Game Engine Architecture, chapitre 14).
J'aurais un petit arbre pour les véhicules. La classe de véhicule racine aurait un composant de rendu, un composant de collision, un composant de position, etc.
Ensuite, un char, une sous-classe de véhicule en hériterait et recevrait son propre composant "canon".
Il en va de même pour les personnages. Un personnage aurait ses propres composants, puis la classe Player l'hériterait et recevrait un contrôleur d'entrée, tandis que d'autres classes ennemies hériteraient de la classe Character et recevraient un contrôleur AI.
Je ne vois vraiment aucun problème avec cette conception. Bien qu'il n'utilise pas un système de contrôleur d'entité pur, le problème avec l'effet de bouillonnement et la grande classe racine est résolu en utilisant une hiérarchie multi-arborescente, et le problème des feuilles de duplication de code lourdes a disparu car les feuilles ne le font pas avoir un code pour commencer, juste des composants. Si une modification doit être effectuée au niveau feuille, c'est aussi simple que de changer un seul composant, au lieu de copier-coller le code partout.
Bien sûr, étant aussi inexpérimenté que moi, je n'ai vu aucun problème lorsque j'ai commencé à utiliser la hiérarchie unique, le modèle lourd d'héritage, donc s'il y a des problèmes avec le modèle que je pense actuellement à implémenter, je ne le ferais pas pouvoir le voir.
Tes opinions?
PS: J'utilise Java, il n'est donc pas possible d'utiliser l'héritage multiple pour l'implémenter au lieu d'utiliser des composants normaux.
PPS: les communications entre les composants se feront en reliant les composants dépendants les uns aux autres. Cela conduira à un couplage, mais je pense que c'est un bon compromis.