Grupo de estudio sobre Go

Ignacio Saporiti

Ignacio Saporiti

See author's bio and posts

A menudo en el mundo del desarrollo de Software nos encontramos con lo que se conoce como  “sobre ingeniería”, es decir , implementaciones que se anticipan a problemas que prevemos que podemos encontrarnos en un futuro. Pensando en términos más de corto plazo, y en tener que desarrollar soluciones muy parecidas a las solicitadas en los requerimientos originales, y  evitar caer en DRY (Don’t Repeat Yourself, No Te Repitas), se termina escribiendo código extremadamente genérico, con algunas características poco explícitas y por por lo tanto, difícil de entender y mantener.

Veamos un ejemplo. Supongamos que para el sprint en el que estamos trabajando nos solicitan una solución que sirva actualizar las publicaciones acerca de la disponibilidad de habitaciones en una página de reservas de hoteles. El programador,  que conoce el modelo de negocio, se anticipa y considera que,  casi con total seguridad, la siguiente petición puede ser, (por ejemplo) una solución que sirva para actualizar publicaciones de paquetes de viaje. Cuando se pone a  trabajar en  la solución para la petición original lo hace de manera que no sea posible replicarla en un futuro para esa otra funcionalidad sobre la que se está anticipando. Esta decisión  es correcta, ya que evitar reutilizar  código es uno de los conceptos básicos de la programación, por lo tanto proceder de ese modo es algo que tenemos muy interiorizado.  Sin embargo, para ese sprint en particular, todo lo que no sea actualizar la funcionalidad de los hoteles no debería ser prioritario.  Al anticipar posibles implementaciones futuras, y tomar decisiones que afectan al trabajo en base a esa anticipación, se está causando un impacto directo en la capacidad de terminar a tiempo el sprint y las tareas relevantes en él. Y lo que es peor, quizás nunca nos pidan aquellas funcionalidades que imaginamos y anticipamos, y por lo tanto habríamos estado trabajando en algo totalmente innecesario. Los programadores somos muy de las siglas, y claro, tenemos una para este concepto: YAGNI (You Aren’t Gonna Need It, No lo necesitarás).

Go, ese lenguaje sencillo que ayuda a no anticiparse 

Hace unos pocos meses empecé a meterme en el mundo de Go, participando en un grupo de estudio que montamos en Codurance. Tenía muchas expectativas, siendo que es un lenguaje muy reciente (su primera versión data del 2009) y al que se lo considera una “evolución” del viejo y querido C, algo así como “el nuevo C++”.

De entrada, Go me llamó muchísimo la atención, porque no incluye algunos conceptos básicos presentes en otros lenguajes como Java, TypeScript, Python, etc. Por ejemplo, Go no permite definir clases ni herencias, ni cuenta con estructuras de control para iterar, como el while. Es por esto que hasta me he encontrado con el chiste de que, más que “el nuevo C++”, Go es “C–”. Bromas aparte, veamos por qué, para mí, es un gran lenguaje.

Se podría decir que es un lenguaje minimalista y humilde, y a priori  esas cosas que “no tiene” pueden interpretarse como carencias. Sin embargo, a medida que se empieza a utilizar el lenguaje, observamos que  podemos resolver problemas de igual manera. Al tener en Go una caja de herramientas reducida, no necesitamos pensar tanto en demasiadas opciones, y nos enfocamos más en aquello que tenemos que resolver. ¿Que no hay clases? Usemos structs y funciones. ¿Que no hay while ni Streams? Usemos un for, sirve igual. ¿Tampoco tenemos herencia? Mejor aún: usemos composición. Encuentro en Go, entonces, un buen aliado para no anticiparme a funcionalidades que no son necesarias para resolver lo que necesito en cada momento con  mi código. Con Go escribimos más fácilmente solo lo necesario, y eso está bien. Nos permite ser ágiles y lanzar a producción funcionalidades más frecuentemente y con confianza. 

Esta simplicidad nos ayuda a ser más explícitos con nuestro código.  Me he encontrado, por ejemplo, con que es una práctica común implementar “a mano” tus propios test doubles (mocks, spies, etc). Al principio pensé que era un poco incómodo, pero con el tiempo, te acostumbras y ves cuánto dependemos de librerías y frameworks para hacer lo mismo en otras plataformas (los estoy mirando, Java y Mockito). Depender menos de código externo te da control casi total, no es tan pesado como uno podría pensar originalmente, y lo mejor de todo: te da libertad  para ser creativo con las implementaciones. Y volviendo al ejemplo con el que hemos empezado este blog: su simplicidad te permite reducir ciertas tendencias a anticiparse que pueden dificultar mucho las tareas y perjudicar el código. 

Hace poco abrimos un grupo de estudio de GO y, aunque el ciclo de esta iniciativa ya ha acabado, nos gustaría invitaros a que veáis los vídeos de las sesiones. En cada una de estos encuentros hicimos katas con el lenguaje, compartimos lecturas, tips y avances, y dimos soporte para mejorar nuestra experiencia con él. ¡Esperamos que os sean útiles!

Primera sesión - Go Study Group: Eficiencia, rapidez de ejecución y facilidad del lenguaje:

 

Segunda sesión - Go Study Group: Structs, métodos e interfaces + Kata:

 

Tercera sesión - Go Study Group: Punteros y manejo de errores:

 

Cuarta sesión - Go Study Group: Inyección de dependencias y test doubles: