Cuando entro en un proyecto que lleva años funcionando, hay una frase que escucho bastante: “Esto habría que hacerlo de nuevo”.
A veces es verdad. Pero muchas otras veces no.
Con los años he aprendido que el código antiguo no necesariamente es mal código. Puede estar desordenado, tener decisiones que hoy no tomaríamos o depender de tecnologías que ya se han quedado atrás, pero también puede llevar mucho tiempo resolviendo correctamente una necesidad real del negocio.
Cuando trabajas habitualmente endesarrollo web a medida, aprendes que entender por qué se tomó una decisión suele ser más importante que pensar inmediatamente cómo la harías hoy.
Por eso intento no entrar juzgándolo ni pensando cómo lo habría hecho yo.
Lo primero es entender qué tengo delante.
Antes de tocar nada, intento entender por qué funciona así
Un proyecto legacy rara vez se vuelve complicado de un día para otro. Normalmente empieza siendo algo bastante razonable y va creciendo poco a poco. Se añade una integración, aparece una necesidad urgente, cambia una API, entra otro desarrollador, se instala un plugin para resolver algo puntual y unos años después tienes varias capas de código que dependen unas de otras.
Aquí suele empezar el problema.
Ves una función enorme, una condición que aparentemente no tiene sentido o código repetido en varios sitios y la tentación es empezar a limpiar. Yo prefiero esperar.
Antes intento saber qué hace realmente esa parte y, sobre todo, qué depende de ella.
En una tienda online, por ejemplo, una función que aparentemente solo modifica un precio puede estar afectando también al carrito, a una factura, a una exportación hacia un ERP o a una promoción que solo utilizan determinados clientes.
Es algo bastante habitual cuando trabajas condesarrollos en WordPress o contiendas online en PrestaShop que han ido acumulando plugins, módulos, integraciones y código personalizado durante años.
Si cambias el código pensando únicamente en lo que ves en pantalla, puedes solucionar una cosa y romper otra bastante lejos de ahí.
Por eso suelo empezar por los procesos importantes: pedidos, pagos, precios, usuarios, formularios, integraciones y tareas automáticas. No intento entender toda la aplicación desde el primer minuto. Intento construir un mapa de las partes que realmente necesito tocar.
Leer el código está bien. Verlo funcionar es mejor
Hay una cosa que hago mucho en proyectos antiguos: reproducir procesos completos.
Creo un pedido, envío un formulario, cambio un producto, ejecuto una importación o intento provocar exactamente el error que me han descrito.
Leer código sirve, pero verlo ejecutarse suele contar una historia mucho más completa.
Esto me lo encuentro muy a menudo. Una función parece hacer una cosa concreta y, cuando sigues el recorrido, descubres que también actualiza otro dato que utiliza una integración varias horas después.
También pasa con los errores que “solo ocurren a veces”. En esos casos, más que intentar adivinar qué está pasando, prefiero conseguir que el sistema deje pistas. Logs, tiempos de respuesta, datos que llegan a una función, respuestas de una API…
Cuando pasas de “a veces falla” a “falla cuando ocurre A después de B”, ya tienes un problema mucho más fácil de resolver.
El error más común es querer arreglar demasiado
Cuando un desarrollador entra en un proyecto legacy es muy fácil preparar mentalmente una lista enorme.
Actualizar PHP. Cambiar plugins. Separar clases. Eliminar código duplicado. Mejorar consultas. Modernizar JavaScript. Rehacer partes del sistema.
Seguramente muchas de esas cosas tengan sentido, pero no necesariamente al mismo tiempo.
Prefiero cambios pequeños y comprobables.
Cambio una cosa, pruebo qué ocurre y continúo. Puede parecer una forma más lenta de trabajar, pero cuando algo sale mal sabes bastante bien dónde mirar y puedes volver atrás con facilidad.
También intento no refactorizar demasiado pronto. Refactorizar significa reorganizar el código sin cambiar su comportamiento, pero hay un pequeño problema: en proyectos antiguos no siempre conocemos completamente ese comportamiento.
Una condición que parece absurda puede estar solucionando un caso muy concreto. Un bloque duplicado puede haberse separado porque dos procesos dejaron de funcionar igual hace años.
Primero intento entender. Después limpio.
¿Rehacerlo desde cero?
Esta pregunta aparece tarde o temprano.
Y mi respuesta normalmente es: depende.
Empezar de cero resulta atractivo porque imaginas una arquitectura limpia, tecnologías actuales y un proyecto sin todas las decisiones antiguas acumuladas. El problema es que cuando empiezas a reconstruirlo descubres que parte de esa complejidad no estaba en el código, sino en el negocio.
Clientes con condiciones especiales, precios distintos, procesos manuales, integraciones antiguas, excepciones que ocurren pocas veces pero tienen que seguir funcionando…
Si no entiendes todo eso, puedes crear una aplicación técnicamente mucho mejor y funcionalmente mucho peor.
Yo solo plantearía una reconstrucción completa cuando existen razones claras: problemas de seguridad, costes de mantenimiento demasiado altos, tecnologías que ya impiden evolucionar o una arquitectura donde cualquier pequeño cambio se convierte en un riesgo.
Si el sistema funciona y se puede mejorar progresivamente, normalmente prefiero hacerlo así.
Si fuera mi proyecto
Intentaría reducir incertidumbre antes que escribir código.
Querría saber qué partes son críticas, qué se rompe con frecuencia, dónde están las integraciones, qué código nadie quiere tocar y qué procesos tienen impacto real en el negocio.
Después empezaría a hacer el sistema un poco más predecible: mejores logs, documentación mínima, entornos de pruebas, copias fiables, algunos tests en las zonas importantes y cambios pequeños que vayan separando responsabilidades.
Nada especialmente revolucionario.
Pero funciona.
Para mí, mejorar un proyecto legacy no consiste en conseguir que todo el código parezca nuevo. Consiste en que cada vez sea más fácil entender qué ocurre, modificarlo con menos miedo y saber qué consecuencias tendrá un cambio.
Después de muchos años trabajando con código de otros, creo que esa es una de las diferencias más importantes: cuando ves algo que no te gusta, no siempre tienes que cambiarlo inmediatamente.
A veces primero tienes que entender por qué sigue ahí.