2010-05-28 6 views
8

He tenido mi cuota de proyectos donde lo primero que pienso es: "Este código es una mierda, solo escribamos de nuevo en framework X". Todo el mundo siente la necesidad en algún momento. De hecho, creo que he tenido la necesidad de reescribir casi todos los proyectos en los que he estado.¿Cuándo ceder y comenzar The Big Rewrite?

Sin embargo, es sabio aceptado que una reescritura total es generalmente una mala idea. La pregunta es: ¿cuándo ves un proyecto y dices: "OK, es hora de empezar de nuevo".

¿Qué tipo de métricas o ejemplos puede citar de dónde una reescritura fue verdaderamente necesaria? ¿Qué tan malo debe ser el código? ¿Qué edad puede tener un proyecto antes de invertir demasiado?

+2

Edad. Cuando una tecnología ha visto mejores días * y * soporte para ella, en términos de programadores, se está reduciendo, es probable que sea hora de escribir algo nuevo. He reescrito los sistemas COBOL, DataFlex y VB6. Se puede argumentar que el soporte para estos sistemas todavía está disponible, pero la mayoría de los programadores quieren promocionarse con las últimas habilidades y, por lo tanto, dejan a las viejas tecnologías en el polvo. Entonces, si tiene problemas para encontrar un programador de DataFlex, entonces sí, probablemente sea hora de volver a escribir. –

+0

¿Qué tal esto: qué pasa si construyes un nuevo producto basado en lo que aprendiste del proyecto anterior que la gente quiere reescribir? ¿Dejar el antiguo y no considerar el nuevo proyecto como parte de la misma línea? –

Respuesta

11

Estoy de acuerdo con Joel, solo debe volver a escribir el software como último recurso.

http://www.joelonsoftware.com/articles/fog0000000069.html

El problema es que todo el mundo piensa en algún momento en el tiempo, que será más fácil volver a escribir algo desde cero, cuando en realidad no lo es. Ese código que ha tenido varias actualizaciones en el tiempo, funciona de cierta manera por una razón. Normalmente hay un montón de pequeños elementos lógicos que se hacen de cierta manera, debido a una actualización o corrección de errores, etc. Cuando reescribe algo, debe imitar el comportamiento de cada uno de esos arreglos, ya que son importantes por una razón. u otro.

Escuchará mucho sobre el análisis de costo beneficio y cuando es bueno reescribir, el problema es que el análisis a menudo es incorrecto. Si lleva un día hacer una actualización simple, todavía es mucho menos que los meses potenciales que probablemente tomará analizar, diseñar, codificar, probar y desplegar la nueva versión.

Mi antiguo jefe y yo solíamos bromear sobre este programa de sistema de colección que la empresa utilizaba. Fue horrible, odiamos mantenerlo. Un día hizo el comentario y tenía toda la razón, "Sabes tanto como odiamos este sistema, funciona. Hace lo que necesita". Ambos coincidimos en que, por más que apestaba, era su trabajo, y al final no lo reescribimos y le ahorramos a la empresa cientos de miles de dólares en la construcción de un nuevo sistema. Pensando en ese sistema, nunca hubiéramos descubierto todos los pequeños detalles. El código era extremadamente difícil de entender, y en última instancia es por eso que queríamos reescribirlo en primer lugar.

+0

Contraejemplo primario: Netscape. La reescritura mató a la compañía. – Joel

+0

+1. Es cierto en muchos casos. A veces el código está mal diseñado. Trabajé en un formato de archivo heredado donde el programador original no compilaba de ninguna manera la extensión del formato. Luego lo extendió usando bits de reserva en ciertos campos para indicar que se había añadido un campo adicional, pero nuevamente no pensó en la extensibilidad. Se hizo imposible agregar nueva información al formato, y golpeó el "último recurso": el formato tuvo que ser rediseñado a un costo de * semanas * de trabajo convirtiendo datos viejos. Debería haber sido reescrito la primera vez que se agregaron extensiones, lo que hubiera costado solo unas pocas horas de esfuerzo. –

7

No vuelva a escribir el software. Refactorizarlo durante toda su vida.

2

Normalmente, ese punto es cuando el Análisis de Costo/Beneficio muestra que una reescritura total va a ahorrar más dinero que mantener el sistema anterior.

Varios factores pueden influir en ese Análisis (como que las plataformas ya no son compatibles, los desarrolladores con talento se vuelven difíciles de encontrar, etc.).

Si realiza el Análisis de costo/beneficio de la manera correcta, verá que nunca vale la pena realizar una reescritura completa. Solo le costará tiempo y dolores de cabeza.

6

reescritura sólo cuando una de las dos cosas es cierta:

  1. El programa existente no funciona de todos modos, y está muy lejos de trabajo. (En otras palabras, heredó una base de código "90% hecho" de sus predecesores, no un producto real.)

  2. El refaccionamiento paso a paso es imposible porque el nuevo programa necesita una arquitectura fundamentalmente diferente, necesita ejecutarse en una pila de tecnología diferente o lo que sea.

En otras palabras, la directriz (hay excepciones, pero son raros; no es probable que salir muy mal después de esta guía) es, volver a escribir sólo cuando paso a paso re-factorización de una producto de trabajo no es una opción.

1

Es posible que desee ver en desarrollo iterativo. Al principio, yo y probablemente casi todos los desarrolladores 'sénior' se avergüenzan cuando leemos sobre ello. Sin planificación anticipada? No pensar en resúmenes y generalidades? Solo hazlo? ¿Eso no produce un código malo? Realmente no. Producirá exactamente lo que necesita y, a medida que vuelva y vea una función diseñada para hacer una cosa, la refactorizará para que haga más, y así sucesivamente.

Esto es efectivamente una reescritura constante pero no real. Esas funciones que nunca se refactorizan se hacen de manera extremadamente rápida y hacen exactamente lo que se supone que deben hacer. También lograste implementarlo en una fracción del tiempo porque no pensabas 10 pasos adelante y lo convertiste en genérico.

Puede comenzar a leer sobre ello aquí: http://www.extremeprogramming.org/rules/iterative.html

Para responder a su pregunta directamente, se adhieren al principio de "Si no está roto, no lo arregles". A menos que haya una necesidad más allá de "Dios es feo, quiero limpiar eso", no reescribas lo que has hecho.

1

Si es tan malo que necesita una reescritura .... llámelo reemplazo. Agregue algunas características nuevas, haga que sea más fácil de mantener y usar. Desarrollarlo con la última tecnología disponible para su empresa.

Los superiores piensan que hay más valor en reemplazar algo que apenas funciona con algo nuevo & mejorado si mejora la productividad del flujo de trabajo &.

Asegúrese de no llamarlo una reescritura del código de mierda, porque las personas que lo escribieron pueden estar todavía allí.

0

Si ya está en un lenguaje moderno, refactorice en lugar de reescribir.

Si tuviera una aplicación Cobol y mi mainframe se fuera con el tiempo, es hora de reescribir. Si encontré una aplicación antigua escrita en FoxPro y todavía necesitamos la funcionalidad, vuelva a escribir.

Pero si está en Java, no importa qué tan malo sea, refactorice bit por bit. Honestamente lastimará menos.

1

Si el código cumple absolutamente cero de los requisitos para el proyecto, podría ser un buen momento para volver a escribirlo.

1

Una de las pocas situaciones donde una reescritura puede ser necesaria es cuando el idioma se ha vuelto obsoleto y no hay desarrolladores disponibles para mantenerlo. En este caso, es posible que tenga que volver a escribir incluso un buen código que funcione perfectamente.

Y para colmo de males, puede terminar fácilmente con algo peor de lo que comenzó.

1

Una "reescritura" (o al menos un poco de refactorización) es a veces la mejor manera de avanzar cuando se da cuenta de que una solución no es escalable.

Un ejemplo de esto es un paquete de pintura que escribo en la década de 1980. Comenzó como un poco divertido trabajando en un mapa de bits de 16 colores. Cuando tenía 20 KB de código BASIC, pensé "Debería reescribir esto para que sea capaz de manejar 16 o 256 imágenes en color". Pero fue "demasiado trabajo". Cuando era de 50kB, estaba claro que realmente necesitaba ser reescrito, pero solo tomaría demasiado tiempo. Así que continué agregando código que dependía de que fuera una imagen de 16 colores, hasta que llegó al punto en que era de 140 kB y completamente imposible de reescribir. Siempre lamenté no haber mordido la bala cuando la reescritura fue solo de unas pocas horas de trabajo.

Otro ejemplo: trabajé en un paquete de arte vectorial que transmitía eventos alrededor de todos los objetos en su jerarquía de escenas. En las etapas iniciales tenía algunas decenas de objetos y, como dijo mi jefe, "podemos transmitir a más de 10.000 objetos por segundo", por lo que las transmisiones continuaron. Sugerí que los objetos interesados ​​se suscribieran a los eventos que necesitaban para eliminar la ineficiencia, pero "no era necesario". 2 años (40 años de esfuerzo) más tarde, el programa se detenía por 2-4 segundos a la vez porque el gráfico de escenas contenía más de 500 objetos y los 2 eventos de transmisión habían aumentado a 40 o más.

Este patrón se ha repetido en varios proyectos en los que he estado involucrado a lo largo de los años: detecta un defecto de diseño serio o una deuda técnica y difiere en solucionarlo porque (a) no es un problema "todavía", y (b) costaría demasiado tiempo resolverlo ahora. A medida que pasa el tiempo, se convierte linealmente en un problema mayor, pero exponencialmente más costoso de arreglar. Por lo tanto, aunque es necesario corregir cada vez más, es más difícil justificar el costo de solucionarlo.

En estos casos, la deuda técnica o defecto de diseño debe resolverse como early como sea posible. Se necesitan agallas (si eres un gerente) o persuasión (si eres un subordinado) para retener tu agenda durante una semana, ¡pero imagina que no tienes más remedio que dedicar 2 meses a la reparación en un año!

Por supuesto, este argumento no se aplica a todos los casos. Debe evaluar el costo/beneficio de cualquier solución propuesta y considerar la escalabilidad del problema: si el problema es constante, puede solucionarlo por el mismo costo en cualquier momento en el futuro. Si cada clase nueva que agregas a tu sistema aumenta la falla, y esperas agregar cientos de clases nuevas, luego regresa y corrige ahora.

1

Uno de los grandes elementos de propaganda sobre la programación es que debe diseñarse para el código, y/o la reutilización basada en módulos. En otras palabras, la funcionalidad debe dividirse en partes reutilizables discretas. Si tiene un código que realmente está haciendo algo y cumple un requisito, entonces el argumento no es que el código deba ser reescrito, sino que debe refactorizarse a un estado en el que pueda reutilizarse.

Esto no significa que no deba tirar grandes trozos de código y reemplazarlos ... De hecho, la idea de refactorizar nos dice que hagamos exactamente eso. Sin embargo, la idea también es que mientras lo hacemos, debemos probar y mejorar para garantizar un comportamiento compatible y una mayor reutilización y modularización.

De hecho, si puede tomar incluso un módulo que hace algo para cumplir un requisito y volver a utilizarlo para ser reutilizable en la "versión 2", entonces, por definición, no ha descartado el código base y comenzó encima. ¿Y por qué querrías, incluso con un código incorrecto, por lo general solo se necesitan algunos ajustes para limpiarlo y convertirlo en un buen código? Por no hablar de las perlas de código decente o incluso "bueno" que existe en el proyecto.

0

La razón por la que está planeando reescribirlo es porque, los problemas que está viendo ahora no fueron premeditados cuando se escribieron, podría haber dos razones para esto 1. No estaba destinado a hacer lo que es haciendo ahora o 2.Fue simplemente un error.

Bríndele un pensamiento muy completo, si puede prever todas las cosas que puede requerir.

Solo luego reescríbelo. Pero generalmente, la mayoría del código bien escrito y bien administrado solo necesita refactorización.

Saludos, Pavan

1

responsabilidad: yo trabajo en una universidad, donde el propósito de software es para establecer o refutar la validez de las nuevas ideas. Mientras que algunos académicos han mantenido el mismo software durante más de 20 años (ejemplos: Glasgow Haskell Compiler y ACL2 theorem prover), muchos académicos abandonan proyectos antiguos y comienzan nuevos proyectos periódicamente. Para muchos de nosotros, la regla de oro correcta es , siempre que el software sigue siendo productiva, mantener y mejorar la refactorización — no empezar de nuevo "productivo" significa cosas diferentes en contextos diferentes, pero algunos ejemplos incluyen:.

  • todavía estás escribiendo artículos sobre el software
  • estudiantes de tercer ciclo todavía están utilizando el software como infraestructura para probar nuevas ideas
  • que haya establecido una importante población de usuarios, y que no quieren dejarlos en la estacada

Para nosotros, una reescritura completa se puede justificar si se ofrece la oportunidad de probar nuevas ideas . Un movimiento más arriesgado para una reescritura completa es intentar tener un mayor impacto. Por ejemplo, estamos en el proceso de reescribir un optimizador en Haskell (fue escrito en Objective Caml) porque al escribirlo en Haskell podemos hacer que más personas lo usen, y podemos establecer su credibilidad al usarlo en un gran esfuerzo de fuente abierta. Pero sigue siendo una jugada arriesgada para nosotros, porque es difícil publicar artículos sobre viejas ideas reescritas en nuevas implementaciones.

La versión corta es que una reescritura completa casi nunca se justifica.