Refactor, Rewrite o Solo Disciplina: Guía para Evaluar tu Sistema Legacy
Tu sistema legacy no está roto. Está cargando años de decisiones.
Cada vez que alguien en el equipo sugiere "reescribir desde cero", hay quien recuerda el desastre de Netscape. Pero tampoco puedes seguir parcheando indefinidamente un sistema que cada día es más difícil de mantener.
¿Cómo decides cuándo es suficiente con refactoring incremental, cuándo necesitas una migración seria, y cuándo el problema no es el código sino los hábitos del equipo?
En este artículo aprenderás:
- Los 3 frameworks técnicos para evaluar código legacy
- Cuándo el refactoring es suficiente (y cuándo no)
- Por qué los rewrites fallan y la excepción válida
- Cómo usar la disciplina como herramienta de mejora continua
- Un checklist de decisión con métricas concretas
- Cómo comunicar esto a dirección sin que suene a excusa técnica
1. El Mito del "Big Rewrite"
El Caso Netscape: La Lección que Sigue Vigente
En el año 2000, Joel Spolsky publicó uno de los artículos más influyentes en la historia del desarrollo de software: "Things You Should Never Do, Part I".
Su argumento central era demoledor:
"They did it by making the single worst strategic mistake that any software company can make: They decided to rewrite the code from scratch."
Los números del desastre:
- Netscape 4.0 salió en 1997
- Netscape 6.0 (nunca hubo 5.0) salió en 2000
- 3 años sin releases significativos
- Resultado: Microsoft Internet Explorer capturó el mercado
¿Qué pasó? El equipo de Netscape miró su código base, decidió que era "demasiado feo para arreglar", y empezó de cero. Mientras tanto, la competencia seguía iterando.
Por Qué el Código "Feo" es Valioso
Spolsky lo explica mejor que nadie:
"When you throw away code and start from scratch, you are throwing away all that knowledge. All those collected bug fixes. Years of programming work."
Ese if extraño que nadie entiende probablemente existe porque un cliente importante tenía un caso edge que rompía todo. Ese workaround que parece innecesario soluciona un bug de un navegador específico que ya nadie recuerda. Esas validaciones "redundantes" atrapan errores que solo ocurren en producción.
El código legacy no es solo código. Es conocimiento institucional compilado.
El Matiz Importante
Esto no significa "nunca reescribas". Significa que debes entender el costo real antes de decidir. Y ese costo incluye no solo el tiempo de desarrollo, sino todo el conocimiento que vas a perder y tendrás que redescubrir.
2. El Framework de Decisión de Martin Fowler
Technical Debt Quadrant
Martin Fowler propuso un modelo para categorizar la deuda técnica que va más allá de "buena" o "mala". Su Technical Debt Quadrant clasifica la deuda en dos dimensiones:
| Deliberada | Inadvertida | |
|---|---|---|
| Prudente | "Sabemos que estamos tomando deuda, pero necesitamos entregar ahora. La pagaremos después." | "Ahora que terminamos, vemos cómo debería haberse hecho desde el inicio." |
| Imprudente | "No tenemos tiempo para diseño. Simplemente hazlo funcionar." | "¿Qué es arquitectura en capas? Solo ponlo donde quepa." |
Por Qué Este Framework Importa
No toda deuda técnica es mala.
La deuda prudente y deliberada es una herramienta de negocio legítima. A veces necesitas entregar rápido para validar una hipótesis de mercado. Tomar deuda técnica consciente para ganar tiempo es válido, siempre que tengas un plan para pagarla.
La deuda imprudente (especialmente la inadvertida) es donde viven los problemas. Es código escrito sin entender las consecuencias, por equipos que no saben que están creando problemas futuros.
Pregunta para reflexionar: ¿Tu deuda técnica es el resultado de decisiones conscientes o de prisa sin reflexión?
3. Métricas para Evaluar (No Opiniones)
Las discusiones sobre "si el código está bien o mal" son subjetivas y generan conflicto. Las métricas te dan un lenguaje común y objetivable.
Technical Debt Ratio (TDR)
Según múltiples fuentes de la industria, incluyendo Brainhub:
TDR = (Tiempo de Remediación / Tiempo Total de Desarrollo) × 100
Benchmarks de la industria:
| TDR | Interpretación |
|---|---|
| < 5% | Código saludable. Mantén el ritmo. |
| 5-10% | Deuda manejable. Dedica tiempo regularmente a limpiar. |
| 10-25% | Requiere atención planificada. Necesitas sprints dedicados. |
| 25-40% | Alerta. La productividad del equipo está afectada. |
| > 100% | Más barato reescribir que arreglar. |
Un TDR de 0.2 (20%) significa que necesitarías invertir el 20% del esfuerzo original de desarrollo para limpiar la deuda. Un ratio arriba de 1 (100%) significa que las cosas están tan mal que podría ser más económico reescribir que arreglar.
Métricas Complementarias
El método SQALE, usado por SonarQube y otras herramientas, propone métricas adicionales:
- Cyclomatic Complexity: Número de paths de ejecución por función. > 10 es señal de alerta.
- Code Duplication: Porcentaje de código duplicado. > 5% requiere atención.
- Defect Density: Bugs por 1000 líneas de código. Objetivo: < 1.
- Test Coverage: Mínimo 80% para sistemas críticos.
Herramientas recomendadas: SonarQube, CodeClimate, NDepend, Codacy.
La Importancia de Medir Antes de Opinar
Un sprint dedicado solo a instrumentar y medir tu código base te da argumentos concretos. En lugar de "el código está feo", puedes decir "tenemos un TDR del 35% y una complejidad ciclomática promedio de 18 por método".
4. Las 3 Opciones Reales
Opción A: Refactoring Continuo
Cuándo aplica:
- El sistema hace lo que debe hacer (funciona)
- La arquitectura base es rescatable
- El equipo puede trabajar en él (no es "código muerto" que nadie entiende)
- TDR < 40%
El Framework: La Regla del Boy Scout
Robert C. Martin (Uncle Bob) adaptó una regla de los Boy Scouts al desarrollo de software:
"Leave the code cleaner than you found it."
La idea es simple: cada vez que tocas código, déjalo un poco mejor de como lo encontraste. No necesitas épicas de refactoring. Solo disciplina constante.
Práctica recomendada: Dedicar 15-25% del sprint a reducir deuda técnica. Shopify dedica el 25% de sus ciclos de desarrollo a esto.
Micro-refactorings que no requieren aprobación de negocio:
- Renombrar variable o función para mayor claridad
- Extraer función de método demasiado largo
- Eliminar código muerto
- Agregar un test cuando arreglas un bug
- Consolidar duplicados cuando los tocas
Opción B: Strangler Fig Pattern (Migración Incremental)
Cuándo aplica:
- El sistema necesita modernización profunda
- No puedes parar la operación para reescribir
- Puedes identificar "costuras" o límites claros entre módulos
Martin Fowler acuñó este patrón inspirado en las higueras estranguladoras que vio en Australia. Según su artículo Strangler Fig Application:
"Like the fig, it begins with small additions, often new features, that are built on top of, yet separate to the legacy code base. As we do this we move bits of behavior from the legacy system into the new code base."
Cómo funciona:
- Identificar la funcionalidad más problemática o crítica
- Crear un façade (proxy) que intercepte requests hacia esa funcionalidad
- Implementar la nueva versión detrás del façade
- Gradualmente mover tráfico del sistema legacy al nuevo
- Eventualmente, el sistema legacy "muere" naturalmente
Ventajas:
- El sistema actual sigue funcionando durante toda la migración
- Puedes medir y comparar el comportamiento nuevo vs. viejo
- Si algo sale mal, el rollback es trivial
- Entregas valor incremental, no un "big bang" al final
Caso real: El equipo de Shopify Engineering documenta cómo aplicaron este patrón para modernizar partes críticas de su plataforma.
Opción C: Rewrite Completo
Cuándo aplica (las únicas excepciones válidas):
- TDR > 100%
- La tecnología base ya no tiene soporte (ej. framework abandonado, lenguaje obsoleto)
- El modelo de datos es irrecuperablemente incorrecto para las necesidades actuales
- No existe nadie que entienda el sistema (y no hay documentación)
Según el análisis de Gartner sobre las 7 opciones de modernización, el rewrite ("Rebuild") es la opción con más riesgo y más impacto.
Requisitos para un rewrite exitoso:
- Presupuesto de 2-3x lo estimado inicialmente (los rewrites siempre cuestan más)
- Timeline flexible que acepte retrasos
- El sistema legacy sigue funcionando en paralelo durante todo el proceso
- No anunciarlo públicamente hasta tener algo funcionando (la lección de Netscape)
Advertencia: Los rewrites tienen un historial notoriamente malo en la industria. Proyectos que sufren retrasos significativos, sobrecostos, scope creep, o que simplemente fallan entregando poco o ningún valor.
¿No sabes qué opción aplica a tu sistema?
En una sesión de diagnóstico analizamos tu arquitectura actual, medimos tu deuda técnica y te damos una recomendación honesta.
Agendar Diagnóstico →5. La Opción Olvidada: Disciplina
A veces el sistema no necesita refactoring ni rewrite. Necesita que el equipo deje de agregar deuda.
Señales de que el Problema es Disciplina, No Código
- Los mismos tipos de bugs aparecen repetidamente
- No hay code reviews, o son superficiales ("LGTM" sin comentarios)
- No hay tests, o los tests no se mantienen actualizados
- Las "soluciones rápidas" nunca se limpian después
- Cada desarrollador tiene su propio estilo de código
- Los pull requests gigantes son la norma
- "Funciona en mi máquina" es una frase común
La Regla del Boy Scout en Práctica Diaria
Según Robert C. Martin:
"If we all checked-in our code a little cleaner than when we checked it out, the code simply could not rot."
La clave está en "a little". No se trata de refactorizar todo el módulo cada vez que lo tocas. Se trata de mejoras pequeñas y constantes:
- Ves una variable mal nombrada → la renombras
- Ves un método de 100 líneas → extraes una función
- Ves código duplicado → lo consolidas
- Arreglas un bug → agregas un test que lo cubre
- Ves código comentado → lo eliminas
Ninguna de estas acciones requiere aprobación especial ni sprint dedicado. Solo requiere que el equipo adopte el hábito.
6. Checklist: ¿Qué Necesita Tu Sistema?
Evalúa tu Situación Actual
- ¿Tienes métricas de deuda técnica actuales? (TDR, complejidad, cobertura)
- ¿El equipo puede hacer cambios sin romper cosas inesperadas?
- ¿Los nuevos desarrolladores pueden ser productivos en menos de 2 semanas?
- ¿Puedes deployar con confianza cualquier día de la semana?
- ¿El tiempo de ciclo (idea → producción) es menor a 2 días?
Si Respondiste NO a Alguna, Evalúa según tu TDR
- TDR < 25%: Refactoring continuo es suficiente. Implementa la regla del Boy Scout.
- TDR 25-50%: Considera Strangler Fig para los módulos más críticos.
- TDR > 50%: Evalúa seriamente una migración incremental planificada.
- TDR > 100% + tecnología obsoleta: Un rewrite puede ser válido (pero mide dos veces antes de cortar).
Antes de Cualquier Decisión Grande
- ¿Tienes buy-in del negocio para el timeline real (no el optimista)?
- ¿Puedes mantener el sistema actual funcionando mientras migras?
- ¿Tienes documentadas las reglas de negocio del sistema actual?
- ¿Tienes tests que validen el comportamiento esperado?
- ¿Hay alguien que entienda por qué existen las decisiones "extrañas" del código actual?
7. Cómo Presentar Esto a Dirección
El problema real: Los equipos técnicos generalmente saben qué hacer. El problema es justificarlo ante quienes no ven el código todos los días.
Framework de Comunicación: Traduce Técnico a Negocio
| En lugar de decir... | Di esto... |
|---|---|
| "El código es legacy" | "Cada cambio toma 3x más tiempo del necesario" |
| "Necesitamos refactorizar" | "Podemos reducir bugs en producción 40% en 3 meses" |
| "La deuda técnica es alta" | "Estamos pagando $X al mes en tiempo perdido por problemas evitables" |
| "Deberíamos reescribir" | "El costo de mantener esto excede el de modernizarlo gradualmente" |
| "El framework está obsoleto" | "Ya no hay desarrolladores disponibles que lo dominen, aumentando costos de contratación" |
La Táctica: Mide Antes de Pedir
Un sprint dedicado a medir métricas te da argumentos concretos:
- Mide el tiempo real que toma hacer cambios (vs. el estimado)
- Cuenta los bugs que llegan a producción por mes
- Documenta los incidentes y su tiempo de resolución
- Calcula el costo en horas/dinero de mantener el status quo
Con datos, la conversación cambia de "los devs quieren reescribir porque les aburre el código viejo" a "estamos perdiendo $X al mes en productividad y $Y en bugs que se podrían evitar".
Conclusión: El Código No Es el Problema, Es el Síntoma
La pregunta "¿refactor, rewrite, o disciplina?" no tiene una respuesta universal. Depende de:
- El estado real del código (medido, no opinado)
- La capacidad del equipo para trabajar en él
- Los objetivos del negocio a corto y largo plazo
- La disponibilidad de tiempo y presupuesto
Lo que sí es universal:
- Mide antes de decidir. Las opiniones sobre código son subjetivas; las métricas no.
- Prefiere lo incremental. El Strangler Fig Pattern existe porque los big bangs fallan.
- No subestimes la disciplina. A veces el problema no es el código, son los hábitos.
- Comunica en términos de negocio. "Deuda técnica" no significa nada para quien no programa.
Y recuerda: ese código "feo" que tanto te frustra probablemente contiene años de aprendizaje sobre los edge cases de tu negocio. Antes de tirarlo, asegúrate de entender qué estás descartando.
Si tu equipo está evaluando modernizar un sistema legacy y quieren una segunda opinión técnica, podemos ayudar.
En una sesión de diagnóstico de 45 minutos:
- Revisamos arquitectura actual y pain points
- Identificamos las "costuras" para aplicar Strangler Fig
- Damos una recomendación honesta (a veces es "solo necesitan disciplina")
Sin pitch de venta. Una conversación técnica entre profesionales.
Tu sistema legacy merece una evaluación objetiva
En MeepLab llevamos más de 10 años ayudando a equipos a tomar decisiones técnicas difíciles. Refactor, migración o disciplina — te decimos lo que realmente necesitas.
Hablar con un Especialista →Referencias
- Things You Should Never Do, Part I - Joel Spolsky
- Technical Debt Quadrant - Martin Fowler
- Technical Debt - Martin Fowler
- Strangler Fig Application - Martin Fowler
- Refactoring Legacy Code with the Strangler Fig Pattern - Shopify Engineering
- The Boy Scout Rule - DevIQ
- 97 Things Every Programmer Should Know: The Boy Scout Rule - O'Reilly
- Technical Debt Metrics - Brainhub
- SQALE Method - Wikipedia
- 7 Options to Modernize Legacy Systems - Gartner
- Refactor vs. Rebuild 2025 - BayTech Consulting
- How to Reduce Technical Debt - vFunction
