Open Dafnemami opened 2 months ago
Hola
Si bien nada esta estrictamente prohibido mientras tenga una muy buena razón para existir en tu código, la creación de híbridos no es estrictamente necesaria (y será penalizada) en este proyecto.
Para entender esto, es importante entender el como queremos comunicar la información de nuestras clases a distintas clases que las usan. Generalmente, queremos esconder la implementación de nuestras clases y exponer solo abstracciones que nos permitan trabajar con nuestros datos. Esto no es lo mismo que esconder nuestra implementación con getters y setters, sino que implica diseñar nuestra solución de tal manera que otras partes de nuestro código no dependan de la representación concreta de nuestros datos. En efecto, una clase que expone todos sus atributos con getters y setters sigue siendo una Estructura de Datos.
Ahora, la distinción más importante entre el paradigma orientado a objetos y el paradigma orientado a estructuras de datos es que ambas estructuras son las opuestas de la otra. Los objetos esconden su implementación mediante abstracciones, mientras que las estructuras de datos exponen su implementación. Dado que una estructura de datos quiere exponer su implementación, no debería tener métodos complejos, ya que estos cumplen la función de esconder la implementación mediante abstracciones.
Si bien, tiene mucho sentido que la clase Unit
sea una estructura de datos, no tiene mucho sentido que esta estructura haga operaciones complejas sobre sus datos, porque su objetivo sería exponer estos datos para que otras clases puedan trabajar con estos (lo que incluye hacer operaciones complejas con estos).
Cuando tomes la decisión de si una clase debiese ser una estructura de datos o un objeto, recuerda que es importante entender las ventajas de cada una de estas estructuras y como estas se relacionan. En particular, creo muy importante la siguiente parte del libro:
Dado lo anterior, si tu clase Unit
expone su implementación, pero al mismo tiempo la esconde mediante funciones, esta caería en al categoría de hibrido. Es importante evitar construir híbridos porque estos combinan las peores partes de los paradigmas orientados a objetos y orientados a estructuras de datos:
En resumen, no crees híbridos, no solo se considerará descuento por estos, sino que también hará que sea más difícil para ti escalar tu solución en las siguientes entregas.
Saludos,
Bueno, después de la cátedra que dió @franciscogazitua, sólo me queda agregar que si puedes tener métodos privados en una EDD, la parte clave es cómo son esos métodos. El libro nos dice que una EDD no debe tener "meaningful functions", a esto se refiere con lógica de negocio y en este caso en particular, con lógica del juego.
Por lo tanto, puede que haya un caso en que haga sentido tener un método privado en una EDD, pero por lo general no.
Hola @franciscogazitua, @cahinostroza . Muchas gracias ambos por sus respuestas, se complementaron bacán!
Sigue siendo confusa para mi cierta idea: Las EDD tienen sus atributos públicos. Entonces, cada vez que por alguna razón algún método -público- lo muestre, cómo puedo manejar ese caso? Pensando que quiero asegurar solo una forma de acceder al atributo. Forma 1: Hago el atributo privado (mal porque es una EDD) Forma 2: No hacer ese método (mala idea también jajaja)
Saludos!
Una EDD no necesariamente debe tener sus atributos públicos, puedes exponer su datos a través de métodos públicos. Por ejemplo:
Ahhh comprendo. Al final el core es que tenga públicos, de alguna forma, todos sus atributos, pero el cómo lo hacemos (si es a través de un método o el atributo mismo) es elección nuestra. Si lo anterior es correcto, creo comprender bacán. Muchas gracias! Me es mucho más claro ahora!!
Quizas la confusión viene porque estas intentando hacer cosas complejas en tu EDD.
Tiene sentido tener atributos públicos y usarlos en métodos públicos para preparar los datos. En un caso sencillo, podrías tener una EDD con un atributo string X1
y un atributo string X2
, si en algun punto necesito retornar un string que use ambas variables, tiene sentido hacer una función pública que haga return $"Tengo {X1} y {X2}"
. Sin embargo la clase dejaría de ser una EDD si hace cosas más complejas, como, por ejemplo, operar con X1
y X2
para determinar algun elemento del juego.
En ese sentido, estaría mal que una EDD que represente la unidad también calcule el daño que esta realizará. Esto porque calcular el daño depende no solo de los atributos de Unit
Entonces una EDD puede "calcular cosas" para entregar data de sus atributos de alguna otra manera con algún método público, pero no se le puede entregar ningún parámetro a sus métodos porque debería poder solo interactuar con sus propios atributos?
Sobre lo primero sofi me parece que no se puede operar de ninguna forma entre los atributos que ya tiene, sino más bien presentarlos de otra forma (como return $"Tengo {X1} y {X2}"
). Lo segundo que dices me parece oki, como que probablemente hacer eso implicaría que estaríamos ocupando lógica del juego en la edd que no es la idea.
En ese caso, en el ejemplo visto en clases
Esto es un objeto o una EDD? Ya que en la segunda implementación para mostrar el porcentaje está interactuando con sus atributos, mostrándolos de otra forma.
Hola
La definición de EDD no tiene nada que ver con la composición los argumentos de sus funciones o con el como esta se construye a nivel de código, sino que tiene que ver con el objetivo de la clase en si. Una EDD expone su estructura interna, permitiendo a otras entidades acceder a sus implementación, mientras que un objeto esconde su estructura interna y provee abstracciones para que otras entidades puedan interactuar con el.
En eses sentido, un objeto es como una caja negra, en el sentido que yo no se que es lo que hace por adentro, solo se cuales son sus entradas y sus salidas. Por otro lado, una EDD es lo contrario, ya que esta me permite acceder a su implementación. En ese sentido, un objeto opera sobre sus datos y expone abstracciones, mientras que una EDD expone sus datos para que otros operen sobre ellos.
Lo anterior no habla de implementaciones especificas en tu código. Podrías tener una EDD con todos sus atributos privados y exponerlos mediante métodos o podrías tener una EDD sin métodos y con todos sus atributos públicos, ambas opciones son válidas.
Como señala @Dafnemami, la idea es que tu EDD no contenga lógica compleja del juego, sino que exponga sus datos para que otros elementos de tu solución puedan ocuparlos para realizar dicha lógica. Si la razón por la que le estas pasando un atributo externo a tu EDD es porque quieres que esta maneje la lógica del juego con estos, entonces tu clase no sería una EDD, sino que sería un híbrido.
En cuanto al segundo ejemplo de la clase (que es el que se discute en el comentario de @siescobedo), este sería un objeto, no una estructura de datos. Esto porque no expone su estructura interna, sino que expone sus datos como una abstracción. Lo bueno de esa implementación es que es irrelevante si Vehicle
guarda sus atributos en galones, litros u otra unidad de medida, double GetPercentFuelRemaining()
solo expone la abstracción en términos de porcentajes. Esto sería cierto incluso si Vehicle
guardara su atributo en porcentaje, lo importante es que la clase que utiliza el método double GetPercentFuelRemaining()
no lo puede saber.
Por favor, no entender lo anterior como que siempre es mejor hacer objetos, estructuras que se componen de agrupaciones de datos (como probablemente sería Unit
) tienen mucho más sentido como EDD que como objetos.
Lo importante es que sepan como manejar sus estructuras tal que haga su solución fácil de mantener y que separe correctamente sus responsabilidades. Recuerden siempre que una EDD y un objeto responden a necesidades distintas y tienen ventajas y desventajas distintas:
Gracias @franciscogazitua! Me es mucho más clara ahora la flexilibidad de las definiciones.
muchas gracias!! me quedo muy claro
Holis!,
Haciendo la entrega me surge la duda si está estrictamente prohibido que las clases bajo el paradigma de EDD tengan métodos privados. Esto pensando en qué veo cierto caso, en mi código de clase Unit/Character, en que necesito preparar ciertos datos antes de retornarlos. Ejemplo: un método público que llama a uno privado. Es eso posible?
La segunda duda que me surge es respecto es si además estos métodos públicos de la EDD son meramente para mostrar los atributos de forma más fácil, como se hace referencia en la cápsula, o si se puede también realizar cálculos dentro de ellos como por ejemplo para calcular el daño que una unidad le inflige a otra. Sumo a la pregunta, que no me hace sentido la definición de método abordada en la cápsula, porque me estaría sugiriendo dos formas de acceder a un atributo.
Gracias 🙉 🙉 🙉 🙉