Buen día, quería saber si algún DOCENTE sería tan amable de ayudarme a disipar una duda que me surgió mientra estudiaba para el final del jueves.
En el ejemplo de los Pokemones, los métodos "dormirse()" y "despertarse()" están declarados en la clase abstracta Pokemon, de la cual heredan Pikachu (que sí necesita esos métodos) y Jygglypuff (que no los necesita). La duda es:
Si en Jigglypuff lo unico que se hace cuando se invoca al método "dormirse()" es siempre lanzar una excepción debido a que el pokemon no se puede dormir, no estamos violando el principio de segregación de la interfaz? dado que estamos obligando a la clase Jigglypuff a implementar un método que no necesita? y además, no estamos utilizando excepciones para controlar el flujo normal de ejecución?
Este problema lo suelo encontrar en muchos ejercicios, donde para favorecer el polimorfismo y utilizar "Double dispatch", me veo en la necesidad de hacer lo mismo que hace Jigglypuff con el método "dormirse()"
Hola ezequiel. No soy docente pero quizás pueda orientar tu duda.
Como controlarías si un Jigglypuff le tira dormirse a otro Jigglypuff? el primero debería poder pegarle a todos los pokemones con el metodo dormir(Pokemon), y al recibir este mensaje utilizan dormirse() y entran en ese estado, salvo en otro Jigglypuff. por eso mismo se utiliza la exception en este ultimo, ya que es una excepción en si misma que ese pokemon no se pueda dormir.
Todos los pokemones heredan de la clase Padre Pokemon, y todos pueden dormirse, a excepcion del Jigglypuff, por eso mismo se utiliza la exception para poder controlarlo y seguir manteniendo el principio de segregacion de intefaz.
A mi me paso lo mismo utilizando DD en algunos ejercicios, mismo en el tp2. Espero haberte ayudado.
Saludos
Hola Ezequiel:
Es algo que depende mucho de cómo sea el caso de uso planteado. La forma en la que fue desarrollado fue planteando que todos los pokemones tienen que tener la necesidad de entender los mensajes "dormirse" y "despertarse" y que cada uno sepa cómo responder de manera polimórfica. En ese contexto tiene sentido que Jigglypuff lance una excepción para cumplir con el requerimiento de que los Jigglypuff no pueden dormirse.
Sin embargo, si siguiéramos iterando sobre el modelo agregando más pokemones y requerimientos, seguramente ya no tenga sentido la existencia de esos dos métodos en la clase abstracta Pokemon dado que tendríamos que crear métodos similares como "quemar()" y "curarQuemadura()", "envenenar()" y "curarVeneno()", entre otros. Eso sería problemático porque, como mencionás, se violaría el principio de segregación de interfaz. Ahí hará falta refactorizar para resumir todos esos métodos en uno solo (o dos) que se encargue de manejar los cambios de estados.
Tené en cuenta que el código de ejemplo tiene apenas unas pocas iteraciones iniciales del ciclo de TDD que satisfacen las pruebas escritas. Para alguien que conoce el dominio del modelo le habría sido más intuitivo considerar estos cambios futuros y se vería tentado a modelarlo de otra forma, pero la idea es ir haciendo crecer al modelo de a poco a medida que se van agregando funcionalidades, dado que sino sería imposible diseñar un modelo ideal desde un comienzo.
En este caso no se usan excepciones para controlar el flujo de ejecución dado que las pruebas requerían que se lanzara esa excepción porque tiene sentido que sea atrapada más arriba para mostrarle al usuario que no puede dormir a Jigglypuff. Si no existiera este requerimiento entonces sí estaría mal.
Por último, respecto a lo último que decís, es cierto y sucede constantemente. Tené en cuenta que double dispatch es simplemente una técnica más entre otras que soluciona la delegación de responsabilidades de una manera muy polimórfica pero que por lo general termina violando el principio Open/Closed. No siempre conviene aplicarlo y dependerá mucho del problema que se quiera resolver y hay que analizar siempre las ventajas y desventajas de cada alternativa.
Saludos,
Tomás
Muchas gracias, me quedó más claro.
Saludos