RodrigoToroIcarte / IIC2113-2023-1

6 stars 0 forks source link

Consuta pauta E3 - CardCollection #109

Open Alzvil opened 1 year ago

Alzvil commented 1 year ago

Buenas tardes

Tengo dudas con respecto a lo mencionado en la pauta de la entrega 3 respectoa un CardCollection, cómo deberíamos crearla y en que casos sería una mala práctica de clean code utilizar List<> como parámetros de funciones o variables.

Gracias!

image

RodrigoToroIcarte commented 1 year ago

¡Hola!

Esta es una pregunta que da pa una conversación larga. Necesito entender mejor el contexto de la pregunta para dar una buena respuesta.

¿Leíste el capítulo 8 del libro? Es un capítulo corto donde se argumentan los beneficios de encapsular librerías externas. Ahí se usa como ejemplo Java.Util.Map -- que es como un Dictionary de Java.

¿Viste la clase 14? Ahí también desarrollo un poco más el argumento dado en el capítulo 8.

Si ya revisaste ambos recursos existe la posibilidad de que no estés del todo de acuerdo con los argumentos entregados. De ser ese el caso, ahí empieza la discusión interesante que podríamos tener al respecto :)

Alzvil commented 1 year ago

Sip los ví y me hacen sentido, aunque mi problema va en qué implementar

Lo primero que se me ocurrió al leer esos capítulos era encapsular view como única librería externa del proyecto para evitar problemas que a veces pasan con cambios en los nombres de algunas funciones en el proyecto base. Pero por lo que hable con ayudantes, por tiempo y al saber que podemos asumir que lo dentro del proyecto base está bien, lo terminé por descartar.

Pero en el caso de algo como una List me hace bastante ruido, al final se me hace un símil al tener que encapsular un string.

No sé muy bien cómo explicar esto sin terminar nombrando código del proyecto pero lo intentaré:

Intenté hacer una clase X que manejaba todas las listas principales A,B,C,D (cada una haciendo referencia a arreglos del elemento n) del proyecto y esa clase tener todas las funciones asociadas a manejar esa lista. Pero claro, si en algún punto necesito que el resto del código pueda ver el contenido de B por ejemplo, eso en el resto del código va a hacer un elemento List y no un elemento X.

Entonces a fin de cuentas, aunque esté semiencapsulado, igual puedo tener funciones afuera que pasen como atributo a B tipandolo como lista. Aquí es donde se me genera un ruido porque ví en algunos ejemplos de las clases para limpiar el código que se entrega como parámetro un objeto CardCollection y no un List por ejemplo. Entonces, bajo el contexto anterior, no sé si sea X una especie de collection o como podría implementar un collection que termine por ocultar que estoy trabajando listas a la hora de pasar su contenido. O, en caso contrario, si es que A,B,C,D tienen que ser c/u un collection y no una lista como atributos de X.

Y claro, ahí estaría el otro problema, porque si simplemente sé en todas partes que son listas, tengo la posibilidad de poder llegar y a hacer un a.Add y b.removeAt, en vez de llamar un metodo de A, luego a otro y después llamar a otro de B (por cómo imagino que podrían ser su funciones que encapsulen a List), por lo que tal vez el código aunque sea más robusto frente a cambios de list, en cantidad de métodos y rapidez de lecturas me lo imagino más sucio.

Entonces, cuando debería pasar un List (que a veces Rider me recomienda un ICollection) o usar una colección creada por nosotros.

Y que pasaría si tengo que usar más listas internar en otra clase? Crear una clase abstracta de la cuál hereden todas mis colecciones?

Y lo último, en algunas clases si tengo por ejemplo el atributo _algo y necesito acceder a un parámetro interno, para no tener que hacer todos los .algo y si cambio alguno tener que cambiar todos sus llamadas, lo que suelo hacer es crear una propertie que oculte esa definición de _algo.mas.nombres.largos por _algo.resumen Aunque no me queda claro su esto es buena práctica de boundaries o presenta problemas de trainwerk y ley de demeter