leanmind logo leanmind text logo

Artículos

Por Carlos Bléel 28/01/2020

Estrategias para mejorar un enorme código legado

Legacy Stamp

A menudo trabajamos con clientes que se enfrentan día a día a repositorios de código de cientos de miles de líneas o incluso millones de líneas, escrito durante más de una década. Son empresas con productos de éxito en el mercado cuyo valor ha hecho crecer a la compañía. Así que ese código legado tiene un alto valor. Eso sí, cuando llega el momento de actualizar el software por cualquier motivo, resulta muy lento y muy costoso. Se convierte en una operación de alto riesgo por todo lo que supone romper funcionalidad existente, lo cual es muy probable porque se trata de código muy frágil. Hace una década nadie escribía test (en estos proyectos no suele haber test). Introducir una nueva forma de trabajar en estos proyectos legados, como por ejemplo añadir test automáticos, se convierte en un gran reto que sería difícil incluso para personas expertas en testing. Así que para el equipo que ha estado todos esos años luchando por hacer evolucionar ese producto de éxito, es todavia más difícil porque se han pasado la vida con la cabeza metida en su problemática particular. Corriendo, enfrentandose a un reto tras otro sin mucho tiempo para pensar en cambiar hábitos o prácticas técnicas. No debemos olvidar el mérito que tiene haber llegado a donde están y el valor que aportan a todos los stakeholders.

En algún momento todos nos damos cuenta de que trabajar sin test de respaldo es demasiado duro como para seguirlo haciendo toda la vida. Empezamos a pensar que para testar ciertas partes del código habrá que refactorizar. Incluso fantaseamos con la idea de tirar a la basura ciertos módulos y escribirlos otra vez, pero ahora con tests.

Y así llegan las grandes preguntas, ¿cómo lo hacemos? ¿por dónde empezamos? ¿cómo le contamos a los jefes que necesitamos tiempo y recursos para refactorizar?

La mala noticia es que un código legado construido a lo largo de una década o más, no se puede domar en unas pocas semanas o meses. Será a lo largo de varios años (fácilmente 4 o 5 años) que conseguiremos haber cambiado el código para que los módulos más críticos queden cubiertos por test automáticos y la legibilidad sea asequible para cualquiera que llegue al proyecto de nuevas. Y no será en todo el código sino sólo en aquellas partes que necesitan ser modificadas con más frecuencia. Una dećada de ingeniería en un proyecto implica una gran cantidad de trabajo y de conocimiento que en parte está ofuscado en el código fuente y en parte está en la cabeza de los programadores más veteranos del equipo. No parece que podamos dar el cambiazo a esta gran obra de ingeniería en unos pocos meses. Si lo pensáramos con una carretera, un puente, una urbanización seguramente entenderíamos que no podemos realizar cambios en cuestión de días sino que hará falta mucho tiempo. Mientras estamos construyendo la nueva carretera, la vieja tiene que seguir funcionando para que la gente siga transitando por donde siempre lo ha hecho. No se puede cortar el tráfico sin más. En algunos puntos del camino la carretera vieja conectará con un tramo de la nueva desviando el tráfico para poder avanzar con las obras y será un poco molesto para todos pero se verá avance, será visible el progreso.

Esta es la forma en que evitamos tener que convencer a la dirección de que nos dejen parar las máquinas y dedicar tiempo a tareas que no van a tener resultados notables, porque ni vamos a parar las máquinas ni vamos a dejar de dar resultados. Lo que cada persona del equipo técnico va a hacer es un esfuerzo sostenible y constante por cambiar sus hábitos, dedicando cada día un poquito de su tiempo a ir añadiendo test y a realizar pequeñas mejoras en el código. Refactoring no significa rehacer ni reescribir ni romper funcionalidad existente. Cuanto más grande es el proyecto más estratégica y delicada se vuelve la refactorización. Hay que estudiar bien lo que se va a cambiar y afrontarlo como un reto de ingeniería, con cuidado, trabajando en equipo. Los días en que tenga menos tiempo, quizás solo pueda dedicar media hora a estudiar el código para ver de qué forma lo podría cambiar. Quizás solo me da tiempo a dibujar diagramas de dependencias o a diseñar planes de prueba para manualmente validar que todo funcione tras los cambios. Los días que tenga más tiempo quizás pueda dedicar dos o tres o cuatro horas a esta tarea de forma que no se aprecie desviación ni perjuicio en el proyecto. Cuando hayan pasado un par de años cada vez seré más eficaz practicando refactoring y escribiendo tests y avanzaré más con menos esfuerzo.

No se trata de engañar a la dirección ni de hacer las cosas a sus espaldas sino de realizar tareas técnicas que no deberían requerir autorización por parte de la dirección, igual que no tenemos que pedir permiso para escribir un bucle o una sentencia condicional. Esto lo conseguimos avanzando en pasos pequeños, sin causar destrozos por el camino. Sin entrar como elefante en cacharrería. Hará falta formación progresiva y continuada en el tiempo y posiblemente apoyo de personas que ya han vivido experiencias similares. Exiten multitud de recursos online para aprender y también empresas como la nuestra que están dispuestas a remangarse y trabajar codo con codo en mejorar ese código legado. A la hora de las ofertas de empleo y las entrevistas también podemos poner el foco en buscar gente con experiencia en estas transformaciones.

Cuando los técnicos somos capaces de ponernos en la piel de la dirección y sentir sus preocupaciones, entender sus necesidades y compartir sus sueños, ya no necesitamos convencerles de que compren algo que no entienden, porque para llegar ahí habremos aprendido a hablar el lenguaje del negocio. Nosotros tenemos la capacidad de aprender a hablar el lenguaje del negocio y el lenguaje técnico. Para ellos es más difícil entender lo que es refactoring, escribir test o mejorar la legibilidad del código. Su energía debe concentrarse en llevar a buen puerto la embarcación mientras que nosotros vamos solucionando cualquier problema que surge por el camino.

Hace un par de años trabajé en un proyecto con más de 6 millones de líneas de código donde inicialmente se nos había planteado reescribirlo por completo. Vimos que reescribirlo por completo era imposible porque no se podía detener la producción durante un tiempo indeterminado. Era imposible estimar lo que nos podría llevar replicar el sistema existente, que además no dejaba de requerir actualizaciones.
Aplicamos el patrón Strangler Fig Application de Martin Fowler que básicamente consiste en ir escribiendo nuevas partes de la aplicación junto al código existente para poco a poco ir reemplazando código viejo por código nuevo. Fue la única forma en que pudimos ver un avance constante tanto en la calidad del código como en la formación del equipo.

Se puede cambiar el legacy code, no es imposible, pero se necesita paciencia, constancia, conocimiento y colaboración.

¿Quieres más? te invitamos a suscribirte a nuestro boletín para avisarte cada vez que recopilemos contenido de calidad que compartir.

Si disfrutas leyendo nuestro blog, ¿imaginas lo divertido que sería trabajar con nosotros? ¿te gustaría?