After-kata, la S de SOLID y una única reponsabilidad
En la entrada anterior, Crónica del #IWT2 DojoUS y la kobuto kata REST-Consumer, vimos la 9ª reunión del #IWT2 DojoUS, un dojo de código que celebramos en la ETSII desde 2.012. Nos quedó pendiente darle un repaso al código que hicimos en el dojo, así que vamos allá. En esa reunión, nos planteamos resolver la kobudo-kata del índice G, que calcula lo guay que es un repositorio de GitHub.
Empezando por el final
Tienes una versión de esta kobudo-kata junto con su enunciado en el repositorio de Kobudo-Katas en GitHub. Anímate a hacerla y a practicar TDD, código para humanos, etc. mientras te conectas a un API REst.
El objetivo de una kobudo kata es aprender, practicar pero también utilizar herramientas que también se emplean en el día a día de la programación, por lo que nos tiramos de cabeza a consumir la auténtica API Rest de Github y trabajar con repositorios reales.
Moviendo datos de acá para allá.
Para calcular el índice G necesitamos las estrellas, watchers y forsk de un repositorio. Como tenemos que mover esta información desde el código que lee repositorios hasta el código que calcula el índice G, la encapsulamos en un sencillo Data Transfer Object que, además, es inmutable.
Este DTO y el servicio que calcula el índice G lo tenéis a continuación (en Python, que fue el lenguaje que utilizamos para la kobudo kata).
Veamos ahora que hicimos para acceder a los repositorios de Github
Al asalto de Github
El código que lee la información e un repositorio de Github y devuelve el DTO se muestra a continuación.
Esta es la parte principal de la kata y la que puede dar más dificultades. Si observas el método get_repos_from de la línea 32 verás que accede directamente a Github. ¿Cómo se puede probar esto? Nosotros utilizamos HTTPretty que intercepta la llamada. Si no tienes, o no quieres usar ninguna herramienta puedes darle un cambio al diseño. Tienes más detalles sobre esto en la entrada anterior.
Sin embargo, aunque funciona bien y se puede probar, el código de la clase RepositoryService (línea 30) no es todo lo bueno que podría ser. Estos son algunos malos olores que yo veo, pero puedes comentar más malos olores o cosas que no te gusten más abajo en los comentarios.
No hay nada que indique que debes llamar a método get_repo y que él ya se encarga de llamar a los otros métodos.
No cumple el principio de single reponsibility.
Tiene una cohesión muy baja ya que los métodos son independientes, incluso podrían ser estáticos.
No hagas llorar al tío Bob
Detengámonos en el principio de responsabilidad única. Este principio, la S de los principios SOLID, nos dice que toda clase debe tener una única responsabilidad, o, en otras palabras que debe tener un único motivo para el cambio. Repasa el código de la clase RepositoryService (línea 30). ¿cuántos motivos para cambiar ves?.
Por ejemplo, imagina que queremos leer repositorios de otra fuente. Tenemos que cambiar la clase RepositoryService. Ahora supón que lo que queremos es cambiar el constructor de la clase Repo porque también queremos guardar el JSon original o porque preferimos utilizar métodos set. También tendríamos que modificar la clase RepositoryService. Sin embargo estos dos cambios no tienen nada que ver entre sí. Hemos descubierto dos responsabilidades diferentes.
Otro ejemplo, supón que algunos repositorios no tiene estrellas. El código que accede a Github será el mismo, pero el método get_repo fallará. Este es otro ejemplo de más de una responsabilidad.
Una de estas responsabilidades es candidata a ir a su propia clase. Tal y como puedes ver en la solución de Github, hemos sacado la responsabilidad de procesar el JSon y construir el DTO a una factoría (línea 48).
Conclusión
Una de las principales ventajas de TDD es que nos empuja a utilizar buenas prácticas de diseño y programación y estás prácticas nos permiten hacer cosas tan interesantes como retrasar las decisiones técnicas y de arquitectura.
Imagina lo siguiente, ¿qué hubiera pasado si, desde el primer momento, hubiésemos querido hacer una aplicación web? ¿Hubiésemos dejado de lado la parte web hasta que ya tuviéramos el código funcionando o, por el contrario, hubiéramos cogido un framework web y hubiéramos empezado a tirar millas?
En la próxima entrada veremos cómo utilizar Django que crear una interfaz web al código que ya tenemos escrito, sin tocar una coma.
Hasta pronto.
















