Un dueño de negocio al que voy a llamar Diego — no es su nombre real — vino a verme con un sistema en VB.NET que manejaba la mayor parte de su operación, y tres consejos que se contradecían de plano. Un consultor le había dicho que reescribiera todo desde cero, "hoja en blanco, hacerlo bien". Otro le dijo que no tocara nada — "si funciona, no lo toque". Un programador al que había contratado para un arreglo chico le dijo que la respuesta real era simplemente traducir el VB.NET a C#, módulo por módulo, y listo.

Los tres tenían algo de razón, y ese es justo el problema. El sistema de Diego no era una sola cosa. Eran varios módulos, construidos en distintos momentos, cumpliendo funciones distintas, envejeciendo a ritmos distintos. La respuesta honesta a "qué hacemos con esto" nunca iba a ser un veredicto único para todo el sistema. Iba a ser una respuesta distinta para cada pieza.

Por qué "todo el sistema" es la unidad de decisión equivocada

La mayoría de los sistemas en VB.NET que reviso no se construyeron de una sola vez. Crecieron — un módulo central primero, después un complemento de reportes dos años más tarde, después una integración agregada cuando apareció un proveedor nuevo, después un panel que alguien necesitó para una reunión de directorio. Cada una de esas piezas tiene su propia antigüedad, su propio ritmo de cambio, su propio radio de impacto si algo falla.

Tratar todo como una sola decisión hace que el módulo más ruidoso y visible (generalmente el que alguien acaba de quejarse) arrastre a todos los demás al mismo veredicto, lo merezcan o no. Un módulo de reportes tranquilo que no necesitó un cambio en tres años no necesita el mismo tratamiento que el núcleo de procesamiento de pedidos que se toca todos los meses.

Las tres opciones reales

Mantener y estabilizar. Es la decisión correcta para un módulo que funciona, cambia poco, y no es donde el negocio está creciendo. El objetivo acá no es modernizarlo — es asegurarse de que siga funcionando con seguridad: confirmar que corre sobre un runtime soportado, agregar pruebas alrededor del comportamiento que realmente importa para que un cambio futuro no lo rompa en silencio, y asegurarse de que el despliegue sea repetible y no algo que solo una persona recuerda cómo hacer. No lo estás mejorando. Te estás asegurando de que no se convierta en un problema por abandono.

Migrar a C# / .NET moderno. Es la decisión correcta para un módulo que se usa activamente, cambia activamente, y donde el negocio depende de que siga evolucionando. Migrar acá no significa una reescritura única y riesgosa — significa avanzar módulo por módulo, con pruebas escritas alrededor de cada pieza antes de tocarla, para poder demostrar que la versión nueva se comporta igual que la anterior. Un detalle que sorprende a muchos dueños de negocio: la lógica de negocio que vive en librerías de VB.NET a menudo se puede reutilizar tal cual mientras solo se reconstruye en C# la capa web alrededor de ella, lo que reduce drásticamente la cantidad real de reescritura.

Reemplazar por completo. Es la decisión correcta cuando el módulo ya no encaja con cómo funciona realmente el negocio — cuando se construyó para un proceso que la empresa ya superó, y mantenerlo con vida cuesta más, en parches y soluciones manuales, de lo que costaría construir algo nuevo. Esta es la opción a la que la gente recurre a veces demasiado pronto (reescribir se siente más satisfactorio que estabilizar) y a veces demasiado tarde (sosteniendo algo que el negocio ya superó, por apego más que por ajuste real).

El sistema de Diego, recorrido en detalle

El sistema de Diego tenía tres módulos reales una vez que lo miramos de cerca.

El primero manejaba el control de inventario — estable, aburrido, tocado tal vez dos veces al año, haciendo exactamente lo que tenía que hacer. Lo mantuvimos y lo estabilizamos: confirmamos el runtime, agregamos un puñado de pruebas alrededor de las partes que importaban, documentamos el despliegue que antes solo vivía en la memoria de un programador. Costo total: unos pocos días. Riesgo continuo: bajo.

El segundo manejaba el procesamiento de pedidos — el módulo que cambiaba casi todos los meses porque el negocio seguía agregando canales de venta nuevos. Este era el candidato claro a migración. Lo movimos a .NET moderno módulo por módulo, mantuvimos en gran parte intacta la lógica de negocio central en VB.NET donde todavía tenía sentido, y reconstruimos la capa web alrededor de ella en C#, con pruebas que demostraban que cada pieza se comportaba igual antes y después.

El tercero era una herramienta de turnos, agregada años atrás para un proceso que el negocio ya prácticamente no usaba. A nadie le gustaba, y todos tenían una solución alternativa para las partes que no encajaban. Lo reemplazamos — no con una reescritura dramática de todo el sistema, sino con una pieza de software nueva, chica y hecha a medida, que realmente coincidía con cómo funcionaban los turnos hoy.

Tres módulos, tres veredictos distintos, ninguno necesitando que los otros dos se movieran primero.

Por qué los sistemas en VB.NET se vuelven más difíciles de dejar como están con el tiempo

Microsoft no le está quitando el soporte a VB.NET — sigue siendo un lenguaje soportado y probablemente lo siga siendo. Lo que no está haciendo es seguir evolucionando el lenguaje; las funciones nuevas van a C#. Eso solo no obliga a nadie a actuar. Lo que sí se va acumulando, en silencio, es todo lo que viene después de esa decisión: cada vez menos programadores quieren construir su carrera alrededor de VB.NET, lo que vuelve la contratación y la capacitación más lentas cada año; las librerías, tutoriales y ejemplos nuevos se escriben pensando en C#; y modernizar la plataforma debajo de un módulo en VB.NET (el runtime, el hosting, las herramientas) muy a menudo implica tocar el propio código VB.NET de todas formas, así que "lo resolvemos después" rara vez sale gratis.

Hacer el inventario antes de decidir cualquier cosa

El proceso que funcionó para Diego, y que funciona en general, empieza antes de tomar cualquier decisión: hacer un inventario de qué hace realmente cada módulo, quién depende de él, qué se rompe cuando falla, y cuánto cuesta — en tiempo, en soluciones alternativas, en riesgo — mantenerlo exactamente como está. Solo después de eso se toma la decisión de mantener, migrar o reemplazar, módulo por módulo, no como un veredicto único dictado para todo el sistema.

Ese inventario es exactamente lo que produce una auditoría estructurada: una imagen clara de qué módulos están bien como están, cuáles vale la pena migrar, y cuáles ya cumplieron su función en silencio — antes de comprometerse con una dirección basada en el último consultor que te haya tocado hablar.

Hablemos de su situación.