Lo admito, he cometido el pecado de abusar e incluso abusar de la herencia. El primer proyecto de juego (de texto) que hice cuando estaba tomando mi curso de OOP fue tan lejos como "Puerta bloqueada" y "puerta desbloqueada" desde "Puerta" y "Habitación con una puerta", "Habitación con dos puertas", y etc. desde "Habitación".
Con el juego (gráfico) en el que trabajé recientemente, pensé que había aprendido mi lección y puse un límite al uso de la herencia. Sin embargo, noté que los problemas pronto comenzaron a aparecer. Mi clase raíz comenzaba a hincharse más y más, y mis clases hoja estaban llenas de códigos duplicados.
Pensé que todavía estaba haciendo las cosas mal, y después de buscarlo en línea descubrí que no era el único con este problema. Así es como terminé descubriendo los sistemas de entidades después de una investigación exhaustiva (léase: googlefu)
Cuando comencé a leer sobre él, pude ver cuán claramente fue capaz de resolver los problemas que tenía con la jerarquía OOP tradicional con componentes. Sin embargo, estos estaban en las primeras lecturas. Cuando me encontré con más ... “radical” ES enfoques, tales como el de T-máquina .
Empecé a estar en desacuerdo con los métodos que estaban usando. Un sistema de componentes puros parecía excesivo o, más bien, poco intuitivo, que probablemente sea la fuerza de la POO. El autor va tan lejos como para decir que el sistema ES es lo opuesto a OOP, y si bien puede usarse junto con OOP, realmente no debería. No digo que esté mal, pero no me pareció una solución que me gustaría implementar.
Entonces, para mí, y resolver los problemas que tenía al principio de la publicación, sin ir en contra de mis intuiciones, es seguir usando una jerarquía, sin embargo, no será una jerarquía monolítica como las que usé antes, sino más bien uno polilítico (no pude encontrar una palabra opuesta a monolítico), que consiste en varios árboles más pequeños.
El siguiente ejemplo muestra lo que quiero decir (esto está inspirado en un ejemplo que encontré en Game Engine Architecture, Capítulo 14).
Tendría un pequeño árbol para vehículos. La clase de vehículo raíz tendría un componente de representación, un componente de colisión, un componente de posición, etc.
Luego, un tanque, una subclase de vehículo heredaría esos componentes de él, y se le daría su propio componente "cañón".
Lo mismo ocurre con los personajes. Un personaje tendría sus propios componentes, luego la clase de jugador lo heredaría y recibiría un controlador de entrada, mientras que otras clases enemigas heredarían de la clase de personaje y recibirían un controlador de IA.
Realmente no veo ningún problema con este diseño. A pesar de no utilizar un sistema de controlador de entidad puro, el problema con el efecto de burbujeo y la gran clase de raíz se resuelve mediante el uso de una jerarquía de múltiples árboles, y el problema de las pesadas hojas de duplicación de código desaparece ya que las hojas no para empezar, tiene cualquier código, solo componentes. Si es necesario realizar un cambio a nivel de hoja, entonces es tan simple como cambiar un solo componente, en lugar de copiar y pegar el código en todas partes.
Por supuesto, siendo tan inexperto como yo, no vi ningún problema cuando comencé a usar el modelo jerárquico pesado de herencia, por lo que si hay problemas con el modelo que estoy pensando implementar, no lo haría. ser capaz de verlo
¿Tus opiniones?
PD: Estoy usando Java, por lo que no es posible usar herencia múltiple para implementar esto en lugar de usar componentes normales.
PPS: las comunicaciones entre componentes se realizarán vinculando los componentes dependientes entre sí. Esto conducirá al acoplamiento, pero creo que es una buena compensación.