Closed PalumboN closed 3 years ago
Hola @PalumboN! que tal? Queríamos consultar con los chicos algo que nos hace un poco de ruido. Nosotros nos juntamos generalmente los domingos a hacer un diagrama y plantear una solución y luego por separado implementamos. Es necesario que cada uno entregue en un repo separado o que todos entreguemos distintas branches con nuestro código para que cuente como entrega para promocionar? Por que nos pareció un poco "duplicar" código o esfuerzos si trabajamos en conjunto luego separar la solución en diferentes branches/repos. Nos sugerís alguna forma particular para realizar las entregas?
Hola @EMazzaglia (y resto del equipo),
Las entregas de estos trabajos son individuales. La idea es que tengan una instancia de ejercitación individual con (eventual) feedback de nuestra parte como práctica para el parcial (que es individual). Re bien que se junten a debatir sobre el diseño, pero después la entrega (comunicación del mismo) estaría bueno que lo hagan individualmente en repos distintos (o en el mismo si quieren, pero aseguren de que cada integrante cargue el formulario).
Yo me confundí al hacer esta corrección con carácter grupal. Esta es una modalidad que sumamos este año y no había entendido bien la ejercitación. Pido disculpas y espero no generar confusión. Cualquier cosa estoy a disposición.
Saludos, Nahue
@PalumboN Ahhhh, jaja te juro que me había mareado. Muchas gracias!
Hola Grupo 10 (@mnigliazzo aseguras que esto le llegue al resto del equipo? Gracias!)
Les hago una devolución general teniendo en cuenta la entrega en
main
como principal pero comparando con las otras soluciones que subieron a otros branches.Lo primero a destacar es lo buen comunicado que está el diseño del sistema. Me encantó ver el diagrama de clases, una breve explicación de los puntos principales de la solución y un pseudocódigo para aclarar dudas de implementación. Una maravilla :clap: Me gustaría agregarle una justificación a esas decisiones que comentan, destacando qué cualidades de diseño se ven impactadas y/o comparando con otras soluciones. Esto un poco ya lo hacen y es algo que iremos practicando.
Respecto al diseño de la solución:
No me gusta el modelo que terminaron eligiendo, caen en un error conocido como primitive obsession: abuso de los tipos primitivos del lenguaje por sobre la definición de abstracciones (objetos) más de dominio. Se ve por ejemplo en los colores que optaron por tener un array de 3 elementos en vez de una clase Color con 3 atributos, poniéndoles nombre a esas 3 cosas. Algo similar pasa con los materiales, aunque habría que analizar el conjunto de materiales (si son muchos o pocos, estáticos o dinámicos, cada cuánto se van a actualizar, etc.) para determinar si solamente se tiene un String, una clase o un enum.
Otro error típico es cómo usan el Repositorio. Es cierto que estos objetos tendrán la responsabilidad de conectar nuestro programa a una base de datos, pero hay que entender bajo qué contexto es necesario. Para que se den una idea de cómo se usaría un repositorio en una aplicación tradicional por ejemplo el ciclo sería: ocurre un evento (por ejemplo se ejecuta un main o se recibe alguna request)
->
La entidad principal que ejecuta el caso de uso le pide a los repositorios (y demás objetos "exteriores", o sea, los acoplados al mundo exterior) los objetos de dominio necesarios para ejecutar el caso de uso->
ejecuta el caso de uso propiamente dicho en el dominio (acá entramos al nivel visto en pdep)->
finalmente otorga una respuesta. Para esta solución en realidad es un sobre diseño más complejo del que debería, mantener un modelo de los tipos de prenda como String y modelar la relación que tiene con la categoría en el repo (o sea en la base) y no-modelarla dentro de los objetos es, de vuelta, no encontrar las abstracciones necesarias en el mundo de objetos. Si se fijan, algo mucho más simple es tener objetos que representen a los tipos y conozcan a su categoría, poniendo la relación en el mundo de los objetos y abstrayéndose de su presentación en los datos. Además de esta forma sale natural el saber qué categoría tiene su prenda, no es necesaria hacer ninguna validación, es un dato que el modelo calcula. Otra opción podría ser tener la relación inversa, en que las categorías conozcan a los tipos de prenda, y que ellas lleven adelante la validación (la anterior me gusta más porque es más simple). Para relacionar esto con los repositorios, al final al repositorio se le pediría los objetos TipoPrenda que por dentro ya conocen su categoría (o al revés) para luego se usado por la prenda y ejecutar el caso de uso.Respecto al
GeneradorDePrendas
: Bien usado el builder, no sé si era necesario para esta instancia pero cumple su función de construir prendas válidas. Esto tiene una consecuencia por cómo está implementado en que obliga a tener setters en la prenda y duplicarlos en el builder. Habría que pensar si queremos que la interfaz de la Prenda tenga los setters, eso haría que se pueda modificar una vez creada llevándola a un estado no-válido. Ya hablaremos sobre mutabilidad o inmutabilidad de los objetos.Respecto al color secundario opcional: El builder ya dejaría crear Prendas con y sin colores secundarios, lo cual está piola tener esa flexibilidad. Veo otras soluciones que solamente lo reciben por setter (y no por constructor). Tengan en cuenta lo mencionado anteriormente y si queremos que una prenda construída pueda cambiar o no. Sino se podría tener 2 constructores.
La validación de
null
: se lanza excepción al intentar obtener una prenda no válida :+1:, que era lo esperado.Atuendo: Por ahora el atuendo no tiene mucho comportamiento porque hay ningún requerimiento más que "tenerlos", pero ya vendrán más requerimientos. Bien.
Cualquier duda la seguimos por acá, no olviden arrobarme!