2012-01-01 18 views
11

Tengo la tarea de mantener un sistema modestamente grande (~ 60k LOC de Perl no Moose OO). Estoy empezando a cuestionar la sabiduría de refactorizarlo en lugar de reescribirlo. Sé que esta cuestión se ha discutido extensamente, pero la situación es inusualmente compleja y tiene varios elementos que apuntan fuertemente en direcciones opuestas, de ahí mi pregunta. Perdón por la verbosidad de la pregunta; es lo más conciso que pude lograr al transmitir toda la imagen.¿Debo abandonar la refacturación y planificar una nueva redacción?

Según el sistema, sus abstracciones son bastante insuficientes para encapsular algo limpiamente, como lo demuestra la dependencia frecuente de la acción a distancia, el uso abundante de bloques if/else con conocimiento íntimo de objetos de un tipo no relacionado con el módulo en cuestión y un gráfico de dependencia que se parece a una red social. Esto, sentí, era malo, pero podría ser refactorizado.

La cobertura de la prueba es irregular. Esto es, por supuesto, reparable y debe ser reparado antes del refactor. Por supuesto, en un sistema como ese, las pruebas necesitan cantidades absurdas de andamios, lo que hace que la mejora de la cobertura de la prueba sea más ardua, pero aún así, es casi imposible.

Y así que había planeado pasar mucho tiempo lentamente ordenando el orden en el caos. Difícil, pero factible, pensé, y el sistema funciona bastante bien para fines comerciales, a pesar de todos sus problemas, por lo que debe estar haciendo algo bien. Y "todos saben" reescribir algo como esto es una receta para el desastre.

Pero recientemente, descubrí que algunas de las partes más vitales y mal escritas del sistema tienen errores de diseño profundamente asentados y serios que llegan hasta el esquema de datos. Toda la metodología tiene problemas importantes (esto es consenso entre los que han trabajado en ella, no solo yo) y las soluciones para eso probablemente constituyen la mitad del código en esa parte, aunque está tan mal escrito que no hay esperanzas de diferenciarlos de los demás. lógica de negocios. El código es demasiado intrincado para mí (solo he estado trabajando en él durante unos meses) o el mantenedor principal anterior (de varios años) para comprenderlo por completo. También tiene menos del 10% de cobertura de prueba.

Nadie confía en que puedan describir completa y correctamente lo que hace esa parte, mucho menos cómo. Obtener una buena cobertura de prueba para esta parte es casi imposible cuando el código es indescifrable y los requisitos que cumple no se comprenden bien. Refactorizar sin cobertura de prueba no es correcto, ni es remotamente práctico en un sistema de este tamaño, complejidad, con problemas tan generalizados (y tipeado dinámicamente hace imposible el descubrimiento automatizado de los impactos de un cambio).

Dejar esta y las esquinas oscuras intactas no es una opción debido a los requisitos comerciales constantemente cambiantes.

La única salida práctica que puedo ver comienza con la redefinición de los requisitos del sistema a nivel comercial y el compromiso de cumplir con esa especificación y arriesgar cualquier rotura que nadie anticipó. Sé que es una mala estrategia, pero no veo alternativa. Si se elige como el camino a seguir, parece que gran parte del beneficio de la refactorización se va por la ventana, lo que me deja cuestionando seriamente la virtud de incluso intentar refactorizar esto.

Esto me lleva a la pregunta específica: ¿La refactorización es una mala estrategia en este caso? Las respuestas respaldadas con experiencias reales son muy preferidas ya que creo que los aspectos teóricos están bien establecidos aquí y en otros lugares.

+3

La gran bandera roja en esto es ... ¡en realidad no sabes lo que hace el código! Seguramente tienes que llegar al punto donde has entendido y documentado el código antes de que puedas realmente considerar seguir adelante. – AmbroseChapel

+1

+1: Creo que esta es una excelente pregunta. No estoy seguro de por qué algunos piensan que es demasiado localizada, ya que esta publicación podría proporcionar una excelente guía para otros en el mismo barco. – Zaid

Respuesta

4

estado allí, hecho eso. El código heredado que actualmente mantengo es el esfuerzo acumulado de varias personas ajenas a la CS (ingenieros) que se propusieron que sus programas logren la funcionalidad requerida sin importar el mantenimiento, la flexibilidad o la escalabilidad.

Pero lo que funcionó para mí puede no funcionar para todos.

En tales situaciones, a menudo es útil enumerar todos los criterios relevantes y sopesar las opciones. Tiendo a hacerme las siguientes preguntas:

  • ¿Su empleador ver el valor de un código de reescritura/refactor?

    Es muy fácil dejarse llevar por Doing the Right Thing, pero hágalo solo si cuenta con la aprobación de su empleador.

    Mi experiencia - si la empresa no ve valor en la reescritura/refactorización, entonces realmente debería poner esta actividad en un segundo plano. Concéntrese en documentar el código existente y obtener una mejor idea de cómo funciona el código antes de intentar escribir/modificar/probar cualquier cosa cuando sea necesario.

  • ¿Con qué frecuencia se agregarán al código las nuevas actualizaciones/solicitudes de funciones?

    Cuanto más a menudo se lleven a cabo tales actividades, más fuerte será su caso para un refactor/reescritura.

    Mi experiencia - es veces más valioso para el negocio que se trabaja con el código existente y aplicar parches bien documentados a ella con modificaciones mínimas.

  • El código tendrá que realizar la función X después de n meses. ¿Qué tan capaz es hoy?

    Esto es aplicable si el desarrollo está en curso. Mire a largo plazo y vea qué debe hacer el código y qué tan bien podría abordar esas necesidades en su estado actual.

    Mi experiencia - Refactorizando veces no cortar la mostaza debido a que el estado actual del código es claramente insuficiente

  • ¿Cuánto tiempo se tarda en poner en práctica los cambios previstos?

    La estimación debe incluir el tiempo requerido para comprender, documentar, implementar, probar, validar y liberar sus modificaciones.

    Mi experiencia - realmente toma mucho más tiempo de lo que se podría imaginar inicialmente, especialmente la validación de la prueba &.

+0

¡Gracias! Esto cubre muchos puntos importantes acerca de la opción de "no hacer nada" que preferiría evitar, pero no obstante puede ser lo mejor y creo que usted ha enumerado algunas buenas razones por qué. – purpleamy

+0

@purpleamy: No estoy diciendo que no haga nada; documentar este código puede ser lo más valioso que puede hacer. – Zaid

+0

Al decir "no hacer nada" quise decir, no intentes arreglarlo. Sin duda, un trabajo de "mejor esfuerzo" para documentar lo que podamos ayudaría, pero no resolverá el peor problema ni nos acercará mucho más a hacerlo. Las partes que más necesitan ser documentadas son poco viables para descubrir y documentar por completo, de ahí mi dilema. – purpleamy

2

Actualmente estoy en la misma posición en un proyecto, pero utilizo un par de factores para decidir cómo debo proceder; con suerte, estos serán de alguna ayuda.

1) Mi mayor criterio es, ¿el proyecto ya se ha lanzado y estamos manteniendo un proyecto o estamos construyendo un proyecto que se va a lanzar?

  • Si estamos construyendo un proyecto para ser lanzado, mi objetivo número 1 es lanzar el proyecto, aunque asegurándome de que no tenga ningún problema de seguridad que no podamos resolver antes del lanzamiento.
  • Si estamos manteniendo un proyecto, estoy mucho más a favor de obtener un código nuevo allí ya que no dañará su base de usuarios actual, pero cosechará las recompensas en el futuro.

2) ¿Cuánto tiempo llevará una reescritura? ¿El nuevo código le ahorrará tiempo en el mantenimiento y el futuro desarrollo?

  • Muchas veces, una reescritura tardará más que la refactorización, pero podría terminar ahorrándole mucho tiempo de mantenimiento y desarrollo en el futuro.

3) He tropezado con algunas piezas de software que están demasiado estranguladas para ser refactorizadas y solo necesitan ser reescritas para que el software pueda funcionar decentemente.

Con el proyecto en el que estoy trabajando ahora, decidí fuertemente a favor o en refactorización porque estamos en proceso de desarrollo y podremos lanzar el proyecto por lo menos 3-4 meses antes si no hagas una reescritura Tenemos planes para una reescritura después de su lanzamiento porque el mantenimiento de esta pieza de software será un inconveniente; tampoco está optimizado ni es lo suficientemente optimizable como para manejar la cantidad de usuarios que tendrá algunos meses después de la publicación del software. , nos damos un par de meses para resolver cualquier error importante y agregar algunas piezas más al software, luego comenzaremos a trabajar en la reescritura.

Por lo tanto, con suerte mi 10 ¢ (2 ¢ + inflación) ayuda. ¡Buena suerte!

4

primer lugar, leer this article sobre por qué no volver a escribir de Joel Spolsky. Luego sugiero que se concentre en las pruebas de escritura, que se necesitarán para reescribir, refactorizar o mantenimiento normal. Una vez hecho esto, revise la pregunta de reescritura/refactorización.

+0

Lo he leído y estoy de acuerdo con el principio que es por lo que considero que la decisión de volver a escribir (o vivir con ella más o menos como es) es difícil de aceptar. Sin embargo, dado el modo en que los problemas interactúan, dudo que una solución puramente técnica como la refactorización sea una solución viable aquí. – purpleamy

+1

+1 para un gran artículo – dantuch

Cuestiones relacionadas