Refactorización continua
Saca a pasear las tijeras de podar
Como he comentado en artículos anteriores, cuidar de una base de código es, en muchos aspectos, parecido a cuidar un jardín. Conforme vamos haciendo crecer el huerto, conforme vamos plantando más y más árboles vamos perdiendo el control poco a poco. Además, las malas hierbas empiezan a salir cada vez que regamos o sacamos una nueva funcionalidad. Sin un buen trabajo rutinario de mantenimiento, el software, como un campo, se nos puede ir de control.
Observa los signos de la maleza
El primer paso que ha de hacer un buen jardinero cuidando de su campo es observar con atención los signos que pueden indicar que las malas hierbas están creciendo. En un proyecto de software estas señales pueden tomar muchas formas.
Si empezamos a leer código que ya lleva un tiempo escrito y nos cuesta mucho entender lo que hace, seguramente necesite un refactor y una mejora de naming que simplifique la tarea de leerlo. Un código bien escrito puede tener sentido cuando se programa, pero que por el contexto necesario que se tiene en el momento de su creación hace que sea difícil de entender pasado un tiempo. Refactorizarlo para hacerlo más accesible a revisiones es una manera de mejorarlo y reducir la carga cognitiva al leerlo.
A veces cierta parte de nuestro código empieza a ser inestable. Nos damos cuenta de que los últimos incidentes que hemos tenido tienen que ver con una parte en concreto de nuestro sistema. Algo que antes había estado funcionando ha empezado a hacer ruido. Eso puede ser signo de que algo se ha degradado. Puede ser porque la cantidad de datos para lo que había sido diseñado ahora es mucho mayor, o que algún cambio en una dependencia de terceros haya hecho que sea más vulnerable. La aparición de errores puede ser una buena señal para que revisitemos esa parte del sistema y aprovechemos para hacer un refactor aquí y allá.
Otras veces tiramos a desarrollar la próxima funcionalidad y nos damos cuenta de que no era tan sencillo como pensábamos. Lo que antes era un sistema aislado ha ido creciendo y ahora depende de varias cosas con las que no contabas. Eso hace que introducir cambios sea más delicado y costoso. El software crece sin control como los arbustos que no se cuidan, es el momento de sacar las tijeras de podar y darle un buen repaso al código.
Como vemos, hay muchos signos que pueden indicar la necesidad de una refactorización. Una buena regla general es que un refactor puede ser necesario cuando nos cuesta hacer algo más de lo que se debería, ya sea entender código, introducir un cambio, arreglar un error, etc. Ese coste añadido es el que pide a gritos “¡Refactorízame!” como si fuera una planta pidiendo agua.
Haz el trabajo
Una vez hemos identificado donde tenemos un problema de deuda técnica o de degradación de nuestro software, es momento de ponernos manos a la obra. Refactorizar y mantener nuestro código es una de las tareas más importantes de desarrollar software, ya que hace que sea más mantenible y más sencillo de cambiar.
Hay diferentes tipos de refactor: simplificar, optimizar, reestructurar, etc. Cada tipo de cambio afecta de una manera diferente al código y tenemos que saber qué tipo de refactor hemos de aplicar para resolver el problema. Al igual que desarrollando producto, cuando estamos ante un refactor el primer paso es saber qué problema estamos resolviendo. No vale de nada identificar que algo va un poco raro y decidir hacer una reescritura completa de esa parte del sistema. Es, como se suele decir, matar moscas a cañonazos (aunque a veces es necesario).
Por lo tanto, identificar que es lo que está yendo mal es el primer paso necesario para continuar con el siguiente paso: hacerle foco.
¿No se entiende que hace cada método? Mejoremos el naming. ¿Se entiende, pero aún no podemos seguir el hilo de lo que ocurre? Simplifiquemos que hace cada cosa y reduzcamos la complejidad. ¿Tenemos todo apiñado y lleno de dependencias que hacen que se rompan un montón de cosas con cada cambio? Reestructuremos el código para que sea más modular y haya menos acoplamiento.
Consejos prácticos
El tiempo me ha enseñado que no hacer el caso que merece el mantenimiento de nuestro software nos puede llevar a situaciones desastrosas donde solo se puede salir cavando hacia arriba. Hay una cosa muy importante y que todos deberíamos hacer en nuestros proyectos: refactorizar continuamente.
No hace falta esperar a que nuestro campo se convierta en un bosque para empezar a podar. Podemos empezar hoy mismo, poco a poco. Aquí os dejo algunos consejos que pueden ayudaros a gestionar mejor vuestras plantaciones:
- Refactoriza continuamente: como he dicho, es una tarea que ha de hacerse de seguido. Después de que cada nueva funcionalidad llegue a producción, cuando se va a entrar a tocar código antiguo o cuando se va a dejar estable código nuevo. No sirve eso de lo que funciona no se toca, porque si algún día quieres tocarlo estarás en problemas.
- Prioriza bien: obviamente no podemos refactorizarlo todo, ni podemos dedicarle la mayor parte de nuestro tiempo de desarrollo. Debemos ser selectivos con lo que aportará más valor a la mantenibilidad y evolución del producto que desarrollamos o desarrollaremos. Al final lo hacemos para poder entregar valor a nuestros usuarios sin que nuestro propio software se nos ponga de por medio.
- Ten un backlog de refactoring (o de deuda técnica directamente): todo lo que no priorices apúntalo en un backlog que te permita tener bien trazado aquello que puede darte problemas en un futuro para atacarlo cuando sea el momento oportuno.
- Hazlo paso a paso: un cambio, una PR. No metas grandes refactorizaciones junto a cambios de comportamiento, solo vas a liar las cosas. Si quieres refactorizar antes hazlo en una PR previa y si te das cuenta de que el código que acabas de escribir puede reestructurarse para encajar mejor con el proyecto, hazlo en una PR posterior.
- Haz boy scouting: muy relacionada con refactorizar continuamente es hacer de boy scout. Esto es hacer que las cosas queden mejor de lo que estaban por allí por donde pases. Muchas veces se trata de aclarar naming, aplicar consensos nuevos que no se habían aplicado en esa zona del código, etc. Ya que estás por la zona ¿Porque no mejorar las cosas?
- Actualiza tus dependencias: hazme caso con esta, si no quieres comerte un mes actualizando versiones de lenguajes, dependencias necesarias y que se van rompiendo, mantenlas actualizadas. Tu yo futuro te lo agradecerá.
Y finalmente, pero no menos importante: hacedlo en equipo. No hay mejor tarea para hacer en pairing o en mob que refactorizar. Coger entre todos un código que da pena y dejarlo como los chorros del oro es una de las mejores sensaciones de desarrollar software. No hay mejor actividad de team building. ¡Buena poda y disfrutad!
TL;DR
Refactorizar continuamente es una práctica esencial para la salud y evolución de nuestro código, como el cuidado de un jardín en constante crecimiento.
La identificación temprana de signos de maleza en la forma de dificultades de comprensión, inestabilidad o complejidad creciente sirve de atención para la necesaria refactorización. La diversidad de tipos de refactorización, desde simplificar hasta reestructurar, exige una comprensión precisa del problema a abordar.
Además, los consejos prácticos, como la priorización inteligente, la ejecución paso a paso y la colaboración en equipo, destacan la importancia de integrar esta tarea como una rutina continua.
La refactorización no solo mejora la mantenibilidad y la capacidad de cambio, sino que también es una actividad colaborativa que fortalece el vínculo entre los miembros del equipo. ¡Buena poda y disfrutad del proceso!