Refactor vs Rewrite

Elegir una transformación para un alcance concreto

Refactor vs Rewrite organiza una decisión: qué conviene transformar preservando la implementación existente y qué conviene reemplazar con una implementación nueva, para un alcance y un cambio justificados. No constituye un ranking de tecnologías ni una obligación de conservar o desechar todo el producto.

Fowler define refactoring como reestructuración interna que conserva comportamiento observable, mediante transformaciones pequeñas que pueden acumular una reorganización importante. Refactoring. Un cambio funcional puede hacerse antes o después; no se convierte por ello en refactoring. Corregir un cálculo y reorganizar sus funciones son trabajos distintos aunque formen parte de una misma intervención.

La frontera observada importa. Fowler señala que cambiar una interface requiere actualizar sus callers para conservar comportamiento; en una published interface, la superficie misma forma parte de lo observable. Is Changing Interfaces Refactoring. No basta conservar la salida de un test ignorando consumidores que quedaron fuera de su alcance.

Qué significa rewrite aquí

El Atlas usa rewrite como reemplazo de una implementación significativa mediante otra construida nuevamente, en lugar de transformarla principalmente mediante una sucesión de refactorings. Es una convención de trabajo: la literatura también habla de replacement, reengineering o renovation con alcances diferentes. No se presenta una taxonomía universal.

Puede reemplazarse un componente, módulo, servicio, subsistema o producto. Tampoco implica empezar sin reutilizar contratos, bibliotecas, modelos, datos o conocimiento. Una implementación nueva puede conservar comportamiento y formar parte de una modernización incremental; su construcción y la manera de introducirla son decisiones relacionadas, pero distintas.

Por eso conviene preguntar «¿reescribir qué?». Cambiar el motor de autorización de Payments no exige sustituir Orders, Inventory y Shipping. Refactoring tampoco equivale solamente a limpieza local: transformaciones sucesivas pueden modificar dependencias y fronteras relevantes sin convertir cualquier mantenimiento en esa técnica.

Preservar, reemplazar y combinar

Un mismo programa puede refactorizar el acceso a un proveedor, reemplazar un motor incompatible, conservar reporting adecuado y retirar una capacidad sin uso. Las decisiones se toman por frontera y obligación, no por una ideología aplicada uniformemente a todo el repositorio.

El trabajo de SEI sobre modernización estudia alternativas y compromisos de desarrollo y deployment incremental, incluyendo coexistencia de componentes anteriores y nuevos. Legacy System Modernization Strategies, 2001. Su contexto no convierte todo reemplazo en una transición idéntica ni justifica copiar sus alternativas como catálogo obligatorio.

«Nunca reescribir» puede prolongar una restricción inviable; «todo lo viejo debe reemplazarse» puede descartar valor sin comprenderlo. La pregunta útil identifica qué resultado se busca, qué parte lo impide y qué evidencia permitiría comparar opciones.

Conocimiento ejecutable y comportamiento deseado

legacy-systems incluye reglas comerciales, datos, edge cases, integraciones, historia de auditoría, procedimientos de recuperación, hábitos y conocimiento organizacional. A veces la implementación es la especificación ejecutable más completa disponible. Eso no demuestra que todo lo que hace sea correcto o deba conservarse indefinidamente.

En Commerce puede haber un refund parcial legítimo, una tolerancia histórica que exige un partner y un error de redondeo. Parecen tres detalles del mismo módulo, pero requieren decisiones diferentes: preservar, negociar una transición o corregir comportamiento explícitamente. Reproducir todo sin revisión puede perpetuar defectos; omitirlo sin conocerlo puede perder obligaciones.

Feathers describe characterization testing como una forma de descubrir qué hace realmente el código. Esa evidencia no establece automáticamente qué debería hacer. Characterization Testing. Casos caracterizados y observación ayudan a detectar diferencias; negocio, contratos y restricciones permiten juzgarlas.

Una prueba de refund existente puede revelar que la referencia del proveedor antiguo todavía es necesaria. No prueba que debamos conservar su formato para siempre. Hay que distinguir comportamiento intencional, defecto, compatibilidad histórica y conocimiento aún incierto, sin llamar regresión a toda diferencia ni mejora a toda salida nueva.

Qué ofrece refactoring y dónde encuentra límites

Cambios pequeños pueden facilitar diagnóstico, conservar feedback de producción y mantener contratos conocidos. Crear una interface alrededor del SDK puede localizar integración y permitir pruebas antes de decidir un reemplazo. modularity, interfaces y testability ayudan a evaluar si esa preparación reduce propagación y ofrece evidencia útil.

También cuesta. La estructura existente puede impedir seams seguros; faltan tests u observación; la plataforma pierde soporte; el modelo de estado entra en conflicto con necesidades fundamentales. Una secuencia local puede acumular tanto trabajo y compatibilidad que ya no resulte la opción más razonable.

Son condiciones para investigar, no reglas deterministas. Ausencia de tests tampoco vuelve fácil reescribir: el problema de conocer comportamiento sigue presente. La viabilidad incremental debe contrastarse con un cambio representativo y obligaciones reales, no con la afirmación de que todo puede refactorizarse sin límite.

Beneficios posibles y riesgos del reemplazo

Reemplazar puede permitir abandonar un runtime sin soporte, un modelo incompatible o una implementación cuyo alcance pequeño ya está bien comprendido. Puede habilitar operaciones imposibles bajo las restricciones actuales o simplificar un coupling que no resulta viable desarmar gradualmente. Cada beneficio necesita un driver y una demostración situada.

El caso de modernización de William Wood en SEI compara alternativas desde mantener hasta reingeniería e insiste en comprender código, datos, usuarios y autoridad antes de decidir. Information Technology Systems Modernization, 2015. Su experiencia informa preguntas; no prueba que una opción gane universalmente.

Una versión nueva puede omitir recuperación, datos peculiares, excepciones regulatorias o reporting. También introduce defectos, incertidumbre y technical-debt nuevos. Su simplicidad inicial puede deberse a requisitos todavía ausentes: al descubrir refunds históricos y conciliación, parte de la complejidad reaparece. Es un riesgo de estimación, no una ley demostrada por una anécdota de reescritura fallida.

Matriz de evidencia, sin puntuación

La tabla organiza preguntas para comparar alternativas del mismo alcance; no calcula una Rewrite Score ni un umbral de deuda:

DimensiónEvidencia que buscar
Conocimiento y comportamientoReglas comprendidas, casos raros, defectos conocidos y consumidores ocultos.
Cambio requerido y horizonteQué debe mejorar, frecuencia probable de cambios y plazo real de soporte.
Datos e integracionesAutoridad, historia, formatos, escritores, lectores y dificultad de transición.
Plataforma y equipoViabilidad del runtime, soporte del proveedor, conocimiento del dominio y habilidades de destino.
Testabilidad y observaciónQué puede prepararse, ejercitarse, compararse y diagnosticarse con confianza suficiente.
Operación y reversibilidadCoexistencia factible, continuidad, efectos irreversibles y opciones de contingencia.
Economía y obligacionesCostos durante el horizonte, capacidad disponible, oportunidad, regulación y compromisos externos.

Un buen conocimiento de la tecnología destino no compensa desconocer el proceso comercial. A la inversa, experiencia profunda en el sistema actual no elimina el costo de aprenderlo para nuevos integrantes. La evidencia incompleta debe hacerse visible como incertidumbre, no ocultarse detrás de una suma de casillas.

La comparación debe mantener alcance y obligaciones equivalentes. Un prototipo nuevo que solo autoriza pagos no puede compararse como si ya sustituyera refunds, conciliación y soporte. Un ensayo acotado puede revelar esfuerzo o una incompatibilidad decisiva, sin demostrar automáticamente viabilidad para toda la capacidad. Conviene acordar qué hallazgo haría reconsiderar cada opción: soporte del proveedor que cambia, imposibilidad de conservar un contrato o costo transitorio que supera la capacidad disponible. Esa revisión conserva opciones y permite detener una inversión que perdió justificación, sin transformar el experimento en una aprobación implícita de la reescritura completa.

Economía de continuar y de cambiar

cost-efficiency permite comparar continuar con soporte, modernizar incrementalmente y reemplazar, durante un horizonte común. Incluir desarrollo, migración, operación paralela, formación, incidentes, soporte y retirada. Comparar solo líneas de código o meses de construcción ignora parte importante del trabajo.

Mantener lo actual puede retrasar features y ocupar equipos en conciliación o fallos repetidos. Reescribir también consume oportunidad: especialistas dedicados al reemplazo dejan de mejorar el producto y deben sostener dos caminos. El baseline de «no cambiar» necesita incluir soporte y riesgo previsibles, no asumir costo cero.

Las opciones tienen valor y costo. Extraer una capacidad primero permite aprender y reconsiderar el resto; mantener dos soluciones durante años puede consumir ese beneficio. Un compromiso amplio reduce alternativas disponibles, pero una sustitución acotada también puede terminar pronto y liberar capacidad. No existe conclusión universal derivada solamente de la palabra incremental.

Deuda, complejidad e intención arquitectónica

technical-debt identifica carga futura; una cantidad elevada no decide automáticamente reemplazo. architecture-erosion pregunta por debilitamiento de intención vigente. Restaurar una frontera, revisar intención o reemplazar una parte son respuestas posibles, con consecuencias diferentes.

accidental-complexity puede reducirse al cambiar una representación y también reaparecer en la solución nueva. essential-complexity conserva distinciones necesarias: devoluciones parciales, vencimientos y conciliación no desaparecen honestamente por cambiar lenguaje. Código difícil no demuestra que todas sus responsabilidades sean prescindibles.

fitness-functions puede evaluar dependencias, contratos o resultados durante la transformación. Pasar checks no decide refactor versus rewrite ni prueba ausencia de pérdidas fuera de cobertura. evolutionary-architecture aporta cambio guiado y revisión de opciones; ninguna etiqueta sustituye juicio basado en evidencia.

Commerce: alternativas sin ganador anticipado

Payments combina SDK antiguo, integración SOAP, refunds maduros, tablas compartidas y conciliación manual. Una opción refactoriza el acceso al proveedor, fortalece autoridad y añade evidencia de comportamiento. Otra construye Payments v2 sobre una API nueva conservando obligaciones seleccionadas.

Si el proveedor actual mantiene soporte y la dificultad está localizada, preparar una frontera puede resolver suficiente problema. Si una obligación necesaria resulta imposible bajo el contrato actual, el reemplazo merece evaluación. Deben comprobarse horizonte, casos históricos, capacidad del equipo y costo de transición antes de concluir.

Orders, Inventory y Shipping siguen operando. Un reporte de BI lee tablas antiguas y un refund puede depender de una transacción creada años antes. Esos usos afectan ambas alternativas. La ausencia de consumers en el diagrama no demuestra que puedan borrarse con la implementación.

Elegir mecanismos y organizar la transición

strangler-fig puede introducir una capacidad reimplementada por incrementos. branch-by-abstraction puede sustituir un motor dentro de una frontera. parallel-change permite migrar contratos o representaciones. Reescribir una parte e introducirla gradualmente son compatibles; ninguna técnica exige un proyecto aislado ni un big bang de todo el producto.

La arquitectura destino responde a architectural-drivers y constraints. Puede seguir siendo Monolith o modular-monolith; Microservices o Serverless no constituyen una escalera de modernidad. Cambiar lenguaje requiere explicar soporte, habilidades y beneficio. Cloud Migration es una preocupación distinta y no obliga a reescribir.

systems-thinking incorpora equipos, operación, usuarios, gobierno de datos y proveedores. Simplificar código local puede trasladar carga a soporte. migration-strategy organiza estados, secuencia, compatibilidad y contingencias después de elegir el alcance de transformación; también puede aportar evidencia para revisar esa elección. evolution-and-modernization conserva separados contexto, decisión, mecanismos y feedback.