TDD y Clean Code

Publicado en

La sensación al modificar el código productivo es abrumante. Tecleas lenta y titubeantemente cada palabra y sentencia. ¿Cambiar un método que ya funciona? ¿Por refactor? ¿Estoy loco o qué? Modificar un simple «if» te revuelve el estómago al pensar en sus múltiples efectos colaterales. Temblar por cada cambio en el sistema, ¿es normal?, no debería de serlo, ¿verdad? Al detectar un problema uno debería tener una sonrisa si conoce la solución, y no quedarse inerte al pensar cómo se atacará ese problema. Es lo que pasa cuando no se tiene la garantía ni la certeza de que mover esa ficha de ajedrez dejará protegido al rey.

Dentro de las responsabilidades del desarrollador está comprobar el correcto funcionamiento del código y que el sistema continúe trabajando en armonía, pero, ¿cómo se tiene la certeza de que el sistema no haya sido dañado? Validar que el sistema siga funcionando y no colapse es posible con ayuda de las pruebas de integración y pruebas unitarias.

Siempre me han llamado la atención esos pequeños aparatos que utilizan los músicos para afinar sus instrumentos; estos garantizan que la guitarra o violín sigan tañendo correctamente, y no hay temor al cambiar una cuerda que ya está vieja. Las pruebas funcionan como ese pequeño aparato mágico que usan los músicos, las pruebas hacen que el sudar frío sea cosa del pasado y que el desarrollador haga adecuaciones con facilidad y libertad.

Las pruebas forman parte de los aspectos más importantes dentro del mundo del Clean Code. Probar el código es tan valioso como producirlo y además es una excelente documentación de las reglas del negocio. Pero no sólo se trata de hacer pruebas por hacerlas; debe haber calidad en ellas y, si se desea una buena integración continua, éstas deben de ser automatizables y ser ejecutadas constantemente. Está prohibido crear pruebas que serán ejecutadas sólo una vez.

TDD

Las pruebas son importantes en el desarrollo del sistema y qué mejor que ese desarrollo esté guiado por esas pruebas de software (Test Driven Development). Es un cambio de mentalidad con grandes beneficios. Escribir primero una prueba y después hacerla pasar es principio de un cambio de esquemas, dando como resultado una efectiva forma de trabajar, en donde los requisitos son traducidos a pruebas y, de este modo, cuando pasan se garantiza que el software cumple con las reglas del negocio. Además, el propósito del desarrollo guiado por pruebas da como consecuencia un código de calidad, limpio y funcional.

Iniciar con la construcción de la prueba ayuda al desarrollador a pensar en el escenario más sencillo; dado este escenario el sistema se verá moldeado como esa vasija de barro que se va adornando poco a poco con detalles más finos.

TDD es una forma de codificar que nos exige disciplina; combatimos la tentación de continuar escribiendo código productivo que aún no ha sido abstraído en una prueba, y hacen de esta práctica un verdadero examen de autocontrol. De seguir tecleando código previsor, los ansiosos dedos han de ser detenidos con freno de mano. Ponemos de manera constante nuestras emociones en el ring, pero el resultado es aplaudido, el código camina orgulloso, sonriente y con la cara en alto, al haber vencido la batalla con esos dedos indisciplinados.

Mi experiencia

Hacer una prueba antes de crear un código productivo me pareció en principio una locura, no una disparatada, pero sí una que no se puede conceptualizar en el mundo real. Cambiar de paradigmas es algo complicado, aun cuando uno está abierto a aprender y conocer sobre nuevas formas de trabajar y programar. Ahora, recapitulando mi pasado, siento que era como Jack, el famoso personaje de Tim Burton, fascinado con la celebración de la navidad, emocionado por conocer el nuevo y sorprendente concepto, pero atrapado por sus percepciones pasadas.

En el tiempo que llevo dedicándome a este bello arte del desarrollo de software, he tenido la oportunidad de estar en muchos equipos de trabajo, y he podido ver líneas de código creadas por principiantes y maestros, pero al día de hoy, hablando de Clean Code, no puedo decir que vi en ellos algo a lo que puedas llamar código limpio. Quizá técnicamente sea código muy bueno, pero seguro a muchos de nosotros nos ha tocado la oportunidad y necesidad de ver y modificar dichas líneas, y al igual que yo han dicho: «quién demonios hizo esto». Me refiero a esas funciones y clases tan largas como una fila de cajero automático en quincena y que, al verlas por primera vez, piensas que es más fácil aprender chino que entender lo que dicha función hace.

Esto provoca miedo de tocar dicho código, porque no sabes qué más vas a romper y entre más le mueves más errores aparecen. Es como si hubieras abierto la caja de Pandora y el fin del mundo estuviera cerca; sólo esperaríamos la promesa de que un día llegará un salvador que rediseñe el software, debido a que el actual es tan poco sostenible que es mejor volverlo a hacer, por salud mental de todos. Prometeríamos que esta vez sí lo haríamos bien. Sin embargo, por más equipo SWAT y expertos que tengamos, ¿sólo las buenas intenciones nos garantizan que las malas prácticas se detengan?

Ahora: ¿por qué Clean Code nos puede ayudar a detener estas malas prácticas? Primero veamos qué es limpiar; su definición nos puede ayudar: «Limpiar: quitar o eliminar lo que estorba o no sirve». ¿Por qué limpiar nuestro código? En primer lugar es para sentirnos a gusto de trabajar en lugar limpio, no es lo mismo llegar a trabajar a una oficina limpia que a una llena de basura. De entrada nos hace sentir mejor. La situación se complica cuando compartimos código; nadie trabaja solo. Es como cuando compartes un departamento. No te gustaría que alguno de tus roomates dejara un desorden en el baño o la cocina justo antes de que tú los utilices. Lo mismo pasa con el código: tenemos que entender que otras personas van a utilizarlo y es profesional no dejarles un desorden.

¿Cómo podemos llegar a tener un código limpio? Es recomendable que dentro de su equipo de trabajo tengan convenciones y estándares para la creación de clases, métodos, funciones y variables que se adecuen al lenguaje de programación que utilicen. Traten de que el código se pueda leer de forma clara de arriba a abajo y de izquierda a derecha, como si se tratara de un libro. El nombrado de variables, funciones y clases debe ser lo más descriptivo posible, sin importar que los nombres sean muy largos al principio.

Sin ser todavía un experto en Clean Code, les puedo compartir que la calidad dentro de mi equipo de trabajo ha mejorado usando técnicas como TDD y principios como SOLID. Métodos que no pasan de cuatro líneas y que hacen sólo una cosa, la hacen bien y lo sabemos, dado que hay una prueba que lo respalda. No pasar más de tres o cuatro parámetros, ya que indica que el método está haciendo muchas cosas. Darle una oportunidad al polimorfismo para quitar varios if, switch y booleans como parámetros. Crear nuevas clases o interfaces basadas en un refactor. Al hacer inspecciones de código se ve la mejora, ya que rápidamente se entiende lo que hace dicho método o clase, y se puede dar una opinión valiosa para mejorar.

Criterios

¿Pero qué es Clean Code? ¿Cómo saber si mi código está limpio? ¿Cómo sé que va a seguir limpio con el tiempo?

A continuación compartiré definiciones que considero muy buenas:

“Me gusta que mi código sea elegante y eficiente. El Código limpio hace sólo una cosa y la hace muy bien”. — Bjarne Stroustrup

“El código limpio es simple y directo. El Código limpio se lee como prosa bien escrita”. — Grady Booch

“Código limpio: pasan todas las pruebas, no contiene código duplicado, expresa todas las ideas de diseño que están en el sistema y minimiza el número de clases, métodos, funciones y todo lo que se le parezca”. — Ron Jeffries

Para mí un código bueno es aquel que puede ser entendido por cualquier programador, pero un código limpio es aquel que puede ser leído y entendido por cualquier persona.

Conclusión

El hábito y la cultura de crear pruebas no es cosa fácil, se necesita confiar en ellas y valorarlas como la forma de seguir haciendo crecer el código. Generar código a partir de las pruebas es todo una aventura, que espero adoptes en tu futuro estilo de programación. El código limpio es esencial para el fortalecimiento de tus habilidades al programar y diseñar sistemas. Usar nombres adecuados y realizar métodos concretos son pequeñas pinceladas que harán ver la imagen más nítida.

Existen grupos y personas que pueden ayudarte en los primeros pasos de Clean Code y TDD. En todas las ciudades se organizan code katas, code retreats o hackathons. Búscalos y anímate a participar.

Referencias

[1] Clean code: A Handbook of Agile Software Craftsmanship (Robert C. Martin)

[2] Test Driven Development: By Example (Kent Beck)

[3] Refactoring: Improving the Design of Existing Code (Martin Fowler)

[4] Working Effectively with Legacy Code (Michael Feathers)

[5] The Clean Coder: A Code of Conduct for Professional Programmers (Robert C. Martin)

Bio

Víctor Luna (victorhugo.lunar@gmail.com) es Ingeniero en Sistemas y después de 8 años desarrollando, ha encontrado en las metodologías ágiles una manera de hacer software con calidad y profesionalismo.

Fernando Arana (fernando0044@hotmail.com) es ingeniero de software y continúa aprendiendo conocimientos y principios de las tendencias de desarrollo. Ambos trabajan en Tralix y colaboran en el blog http://codeamesta.blogspot.com