¿Cómo arreglar un proyecto básicamente sin estructura?

25

He estado trabajando en un proyecto de software principalmente en solitario durante más de 5 años. Para empezar, fue un desastre (soy el tercer o cuarto desarrollador que está trabajando en ello), y aunque ahora es menos complicado, todavía está increíblemente desorganizado. La tasa de progreso para mantenerlo bajo control es glacial y estoy empezando a sentirme abatido por el estado en que se encuentra. ¿Cómo empiezo a arreglarlo realmente?

Detalles del proyecto: es un programa de ventas escrito casi en su totalidad en Visual Basic Classic (VB6) con un back-end MySQL y un motor de informes escrito en C #. Es un placer trabajar con el módulo de informes de C #, solo se escribió en los últimos años y antes de que todos los informes se hicieran en Crystal Reports 9 (sí, todavía tenemos algunos informes que dependen de él).

Sin embargo, el programa en sí mismo es un completo desastre. No hay un total de 90k LOC en total, y alrededor de 10k líneas de comentarios (en su mayoría no son documentación, sino código antiguo que ha sido comentado). 158 archivos de formulario y 80 archivos de módulo. No tengo idea de cuántos de ellos se usan realmente, porque algunas características del programa simplemente están en desuso y (uh, a veces) se notan como tales sin que se elimine el código asociado del programa. Supongo que solo el 50% del código está en uso productivo real.

Tengo miedo de tocar gran parte del código solo porque no estoy seguro de si estoy rompiendo algo en lo que confía un cliente oscuro, ha sucedido en más ocasiones de las que puedo contar. Es como si hubiera minas terrestres esparcidas por todo el código.

Realmente no hay ninguna estructura para el proyecto. No está orientado a objetos, excepto en los pocos lugares donde he tenido la paciencia para reformar hasta ahora. Si necesita obtener datos en un formulario, crea una instancia de un objeto de base de datos, declara su consulta allí mismo en la función, la ejecuta y hace lo que quiera con el conjunto de datos.

Cuando comencé a trabajar en el proyecto no había control de fuente en uso. Traté de alentar a las otras personas en las que estaba trabajando para que lo usaran, pero yo era el chico nuevo y mis intentos de hacer que la gente usara la subversión fallaron. El desarrollador principal de la compañía finalmente detectó un error mercurial en los últimos años y se aseguró de que todos los desarrolladores usen el control de origen en todos los proyectos ahora, así que al menos eso es un progreso.

Creo que si pudiera trabajar en la reforma del proyecto a tiempo completo, podría lograr un progreso decente y tal vez incluso tener una estimación de cuánto tiempo me llevaría cambiar completamente el proyecto, pero está en uso activo y estoy se le pide constantemente apagar incendios, corregir errores, agregar funciones, etc., etc.

Entonces, ¿cómo empiezo a arreglar realmente este proyecto? ¿Intentas equipar VB6 con otro idioma? ¿Intenta reescribir el programa en mi tiempo libre? ¿O es esto completamente inútil?

Actualizar

Después de esta publicación, volví al proyecto con renovado celo, pero volví a la desesperación unos meses después de ver un ritmo de progreso tan lento. Luego repetí este ciclo 2 o 3 veces más durante el próximo año más o menos.

Desde entonces me mudé a un trabajo diferente. Aunque después de tantos años de vb6, y solo experiencia periférica con otras tecnologías, la búsqueda fue difícil y enfrenté muchos rechazos en el camino (alrededor de una docena de entrevistas en el transcurso de un año). Mi consejo para otros en esta situación es considerar dejar solo este factor. Considere el daño que puede hacer a su carrera al permanecer en una posición de callejón sin salida como esta.

Dylan Nissley
fuente
44
Suena bastante mal Un comienzo sería guardar una copia del código actual y eliminar el código anterior que ha sido comentado (eso es solo ruido). Cuando trabajaba en un sistema heredado, generalmente ponía una fecha en la parte superior del código que comentaba. Luego, elimine el código comentado que tenía 6 meses o más.
programador
44
Comenzaría con Jamison y avanzaría por el estante. . .
Wyatt Barnett
1
¿Alguna vez ha intentado hacerse cargo de un proyecto C # escrito por un programador de VB?
שינתיא אבישגנת

Respuestas:

28

Ahora que está en control de código fuente, puede deshacerse del código comentado.

Empecé aquí en una situación similar (aplicación 80KLOC VB6 sin control de fuente, sin estructura real, casi todo hecho en controladores de eventos).

En aproximadamente 2 años, he convertido más de la mitad a C # (generalmente cuando se requieren nuevas características significativas). Todo el nuevo código C # tiene cobertura de prueba unitaria. Sin embargo, definitivamente lleva más tiempo convertirlo a C #. Si no está agregando módulos nuevos significativos, no seguiría esa ruta.

Una cosa que hice fue crear una capa de acceso a datos rudimentaria que se generó automáticamente a partir de la base de datos. Eso al menos detectó problemas en los que cambió el nombre de la columna de una tabla y no encontré todos los lugares en el código. Además, lentamente moví la lógica de negocios a módulos, fuera de los controladores de eventos de formulario.

Yo, sin embargo, tenía la ventaja de que la aplicación era solo interna. Dado que solo tenía un sitio para implementar, podría tomar algunos riesgos más grandes que usted. Si cometía un error, generalmente no era un gran problema arreglarlo. Parece que no tienes ese lujo.

Realmente creo que su mejor apuesta es adoptar el siguiente enfoque:

  1. Aprende cada detalle con detalles insoportables. Esto hace que sea menos probable que rompa algo sin darse cuenta.
  2. Refactorice sin piedad para mejorar la separación y la estructura, pero no intente calzar una nueva metodología, como la programación orientada a objetos, ya que VB6 simplemente apesta.
  3. Trátelo como una experiencia de aprendizaje. ¿Cómo sabrías que una forma diferente es mejor si nunca hubieras visto la inferior?
  4. No se moleste en volver a escribir en un nuevo lenguaje / marco / plataforma a menos que tenga un módulo importante para escribir. Incluso entonces, considere cuidadosamente.

Recuerde, el objetivo del programa es ser un producto que le haga ganar dinero a su empresa. No tiene que ser una obra de arte perfecta (y soy un perfeccionista, así que es muy difícil admitirlo). A veces es mejor abrazar el pragmatismo.

Supuestamente, hay muchos programadores de COBOL que mantienen grandes cantidades de código heredado. Dudo que todos estén locamente trabajando para reescribirlo en algún idioma nuevo. :)

Scott Whitlock
fuente
3
+1 Gran respuesta: todo lo que puedo agregar es estar seguro de que no te esperas demasiado. El mantenimiento del código es lento en comparación con el nuevo desarrollo, el código heredado, incluso el código no estructurado, más lento e indocumentado, tal como lo ha descrito ... SLOC ... Conozco tu dolor ...
mattnz
+1 pero una característica OO VB6 funciona bien en Interfaces. Si puede ver un código similar copiado y pegado varias veces, es posible que pueda refactorizar en una interfaz, si no en una clase completa.
Mark Hurd
3

Lo que debes hacer es refactorizar. Refactorizar es casi imposible en tal situación sin una prueba unitaria que le brinde la confianza de que no ha roto nada. Por lo tanto, comience con la creación de pruebas unitarias. Documente el comportamiento del código, pero no (solo) en papel, sino en más código, la unidad prueba. Una vez que tenga las pruebas en su lugar, puede comenzar a reestructurar el código.

usuario281377
fuente
11
He estado en esta situación. Primero, VB6 tiene lamentables suites de pruebas unitarias. En segundo lugar, las pruebas unitarias casi siempre requieren DI y eso es realmente difícil en VB6 debido a su terrible soporte para la programación orientada a objetos. Todavía tengo que escuchar a alguien que tomó un proyecto VB6, escribió un montón de pruebas unitarias y realizó una borrachera de refactorización, incluso si es la respuesta estándar que siempre escuchará para una pregunta como esta en Programmers.SE. ¿Sabes lo doloroso que es escribir pruebas unitarias para la lógica que está incrustada por todas partes en los controladores de eventos de Formulario? ¡Tienes que refactorizar antes de poder escribir pruebas!
Scott Whitlock
Me encantaría agregar pruebas unitarias a nuestro código, pero no sé por dónde empezar. He realizado algunas pruebas unitarias en .net y otros idiomas, pero solo desde cero, nunca agregué pruebas a un proyecto existente. ¡Y ninguna de las pruebas unitarias que he realizado ha sido en programas que usan GUI, especialmente no GUI con una gran cantidad de bases de datos y lógica de negocios entremezcladas en los controladores de eventos!
Dylan Nissley
1
Si el código no fue escrito para ser comprobable, todo lo que hará es escribir pruebas unitarias que cubran los casos fáciles y obvios, y omita los casos extremos que causan el 90% de los defectos. He estado allí, hecho eso, desperdicié una gran cantidad de tiempo y esfuerzo (lea Money). El mejor enfoque es asegurarse de que el código que cambie sea fácilmente comprobable, lo que sea que eso signifique en el entorno que tiene, que no suena como pruebas unitarias.
mattnz
3

Me viene a la mente una regla de la " Depuración " de David Agan : dejar de pensar y mirar. Tienes a tu disposición una máquina capaz de procesar grandes cantidades de texto. Úselo para determinar con precisión qué código ya no está en uso, y elimínelo sin piedad. Si comete un error, para eso está el control de fuente.

Esa es la parte fácil. Lo que debe pensar a continuación es cómo se come un elefante. Un bocado a la vez. Elija " Refactorización " de Martin Fowler y tómelo función por función, archivo por archivo. No deseche completamente algo y reescríbalo de lo que cree que son los requisitos. Trabaja como un alpinista, nunca elimines tu seguridad anterior hasta que la siguiente esté en su lugar.

¿Ya tenía suficientes metáforas? El punto es que si lo toma de manera lenta y constante, con muchas mejoras tan simples como cambiar el nombre o dividir una función, puede mejorar las partes defectuosas del código sin destruir las partes buenas que se construyeron a través de años de depuración y solicitudes de funciones . Desea que el código se pueda enviar en todo momento. Si es posible hacerlo mientras se transfiere a un idioma más moderno, hágalo.

Karl Bielefeldt
fuente
A menos que se haga correctamente, "Portar a un lenguaje moderno" dará un "programa VB en sintaxis C #". Actualmente trabajando en una aplicación C portada a Java que realmente es "Cava", no Java, es lo peor de ambos y lo mejor de ninguno ........ Portar correctamente es realmente una reescritura en arrastre, y como lo expresó Joel, eso está muy arriba en la lista de "cosas que no hacer".
mattnz
Buen punto. Por eso dije "si es posible". Si no puede hacerlo poco a poco y también escribe el código portado idiomáticamente, no debe intentarlo.
Karl Bielefeldt
3

Odio decirlo, pero iría con "completamente desesperado" más allá de continuar haciendo un ciclo interminable de parche / mejora y espero que nada se rompa. He visto demasiados proyectos de VB6 como el que usted describe e intenta refactorizar / reescribir / rehacerlos en C # / .NET fallan terriblemente, a menudo con las personas a cargo del intento de ser despedido.

La cuestión es que una reescritura completa desde cero será necesaria tarde o temprano. Las versiones de VB6 y Windows que lo admiten bien están en declive. Encontrar desarrolladores que conozcan las peculiaridades de VB6 y que estén dispuestos a trabajar en programas como este se está volviendo cada vez más raro. Los límites internos de VB6 se verán afectados en grandes programas como este, causando errores extraños.

Si hay un buen consenso y compromiso para un total, comenzar, rediseñar y reescribir en este punto, comience a trabajar en él y delegue el mantenimiento continuo a otra persona (contratistas, programadores junior, lo que sea que funcione para usted). Si las personas aún no están lo suficientemente convencidas como para comenzar esto, solo espere a que el dolor se vuelva lo suficientemente fuerte o de lo contrario continúe con pastos más verdes.

jfrankcarr
fuente
+1 Tienes razón acerca de que VB6 pierde soporte en las versiones modernas de Windows. Tarde o temprano (probablemente antes), su aplicación simplemente dejará de funcionar donde sea necesario.
Bernard
1

Algunas buenas respuestas aquí ya, me gustaría agregar una cosa. En lugar de intentar reescribir todo, ¿quizás tenga la oportunidad de transferir al menos algunos de esos módulos, principalmente 1: 1 a VB.NET (por supuesto, debe tener mucho cuidado al hacer esto)? Según mi experiencia, dicha transferencia se puede realizar con ~ 5-10 veces menos esfuerzo que intentar reconstruir todas las funciones existentes desde cero. Y después de haber portado, a continuación, puede empezar a refactor - con todas las herramientas disponibles en el mundo .NET, como buenas herramientas de pruebas unitarias, herramientas automáticas de refactorización, programación orientada a objetos reales etc.

Había estado en una situación similar, donde tuvimos que migrar un viejo programa C ++ de 16 bits (150k LOC) al mundo de 32 bits, donde el marco GUI original en uso ya no estaba disponible. Nos tomó un tiempo comprender que la reescritura no era realista, pero después de que decidimos trasladar esa cosa al mundo .NET, usando C ++, C ++ / CLI y C #, solo necesitábamos unos 9 meses para que eso sucediera (con alrededor de 1 dev trabajando a tiempo completo en ese proyecto). Y no teníamos pruebas unitarias para la parte GUI disponible, hicimos todas esas pruebas de esas partes manualmente.

Doc Brown
fuente
0

Aunque pone MUCHO énfasis en probar la aplicación de su unidad que, aunque es algo muy importante que hacer, es algo bastante difícil de hacer en VB6, Steven McConnell escribió un excelente libro sobre cómo abordar un proyecto de este tipo.

Mira esto:

Steven C. MCCONNELL: Trabajando efectivamente con código heredado, segunda edición. Microsoft Press, junio de 2004.

Básicamente, su punto es tomarlo con calma, un poco a la vez. También recomienda comenzar usando técnicas de refactorización que son muy poco probables de romper algo, a veces empeorando un poco a corto plazo, y comenzar a usar técnicas más avanzadas ya que el código se está volviendo más limpio y tiene pruebas unitarias para respaldarlo.

QuantumOmega
fuente