Pregunta

Supongamos que tiene un programa que actualmente funciona de la manera que se supone. La aplicación tiene un código muy deficiente, consume mucha memoria, no es escalable y se necesitaría una reescritura importante para implementar cualquier cambio en la funcionalidad.

¿En qué punto la refactorización se vuelve menos lógica que una reconstrucción total?

¿Fue útil?

Solución

Joel escribió un buen ensayo sobre este mismo tema:

Cosas que nunca debes hacer, Parte 1

La lección clave que obtuve de esto es que aunque el código antiguo es horrible, lastima tus ojos y tu sentido estético, existe una gran posibilidad de que gran parte de ese código esté solucionando errores y problemas no documentados. Es decir, tiene muchos conocimientos de dominio incrustados y le será difícil o imposible replicarlo. Estarás constantemente golpeando contra errores de omisión.

Un libro que encontré inmensamente útil es Trabajando con eficacia con el código heredado por Michael C. Plumas. Ofrece estrategias y métodos para abordar incluso el código heredado realmente feo.

Otros consejos

Uno de los beneficios de la refactorización sobre la reconstrucción es que SI puede hacer la refactorización paso a paso, es decir, en incrementos, puede probar los incrementos en el contexto de todo el sistema, haciendo que el desarrollo y la depuración sean más rápidos.

El código antiguo e implementado, incluso cuando es feo y lento, tiene la ventaja de haber sido probado exhaustivamente, y esta ventaja se pierde si empiezas desde cero.

Un enfoque de refactorización incremental también ayuda a garantizar que siempre haya un producto disponible que se pueda enviar (y está mejorando constantemente).

Hay un buen artículo en la web sobre cómo se escribió Netscape 6 desde cero y fue En cuanto a los negocios, una mala idea .

Bueno, la respuesta más simple es si demorará más en refactorizar que en reconstruir, entonces deberías reconstruir.

Si se trata de un proyecto personal, es posible que desee reconstruirlo de todos modos, ya que probablemente aprenderá más de la construcción desde cero que de la refactorización, y ese es un gran objetivo de los proyectos personales.

Sin embargo, en un entorno profesional de tiempo limitado, siempre debe ir con lo que le cueste a la empresa la menor cantidad de dinero (para la misma recompensa) a largo plazo, lo que significa elegir lo que requiera menos tiempo.

Por supuesto, puede ser un poco más complicado que eso. Si otras personas pueden trabajar en las características mientras se realiza la refactorización, entonces esa podría ser una mejor opción en lugar de que todos esperen a que se construya una versión completamente nueva. En ese caso, la reconstrucción podría llevar menos tiempo que solo la refactorización, pero debe tomar en cuenta todo el proyecto y todos los colaboradores del proyecto.

Cuando dedicas más tiempo a refactorizar que a escribir código.

En el punto donde el software no hace lo que se supone que debe hacer. Refactorizar (cambiar el código sin cambiar la funcionalidad) tiene sentido si y solo si la funcionalidad es " como se pretende " ;.

Si puede permitirse el tiempo necesario para reconstruir completamente la aplicación, no necesita mejorar la funcionalidad de manera incremental y no desea conservar ninguno de los códigos existentes, entonces la reescritura es una alternativa viable. Por otro lado, puede usar la refactorización para realizar una reescritura incremental al reemplazar lentamente las funciones existentes con funciones equivalentes que estén mejor escritas y sean más eficientes.

Si la aplicación es muy pequeña, puede volver a escribirla desde cero. Si la aplicación es grande, nunca lo hagas. Vuelva a escribirlo de forma progresiva, un paso a la vez para validar que no rompió nada.

La aplicación es la especificación. Si lo reescribes desde cero, lo más probable es que te encuentres con muchos errores insidiosos porque "nadie sabía que la llamada a esta función debía devolver 3 en ese caso muy específico". (comportamiento indocumentado ...).

Siempre es más divertido volver a escribir desde cero, por lo que tu cerebro podría engañarte para que pienses que es la elección correcta. Ten cuidado, lo más probable es que no.

He trabajado con este tipo de aplicaciones en el pasado. El mejor enfoque que he encontrado es gradual: cuando esté trabajando en el código, encuentre cosas que se hacen varias veces, agrúpelas en funciones. Mantenga un cuaderno (ya sabe, uno real, con papel y un lápiz o bolígrafo) para que pueda marcar su progreso. Úsalo en combinación con tu VCS, no en lugar de él. El cuaderno se puede usar para proporcionar una visión general de las nuevas funciones que ha creado como parte de la refactorización, y el VCS, por supuesto, llena los espacios en blanco para los detalles.

Con el tiempo, habrá consolidado una gran cantidad de código en lugares más apropiados. La duplicación de código durante este período de tiempo será casi imposible, así que hazlo lo mejor que puedas hasta que hayas alcanzado un punto en el que puedas realmente iniciar el proceso de refactorización, auditando todo el proceso. base de código y trabajando en ello en conjunto.

Si no tienes suficiente tiempo para ese proceso (que llevará mucho tiempo), entonces es mejor volver a escribir desde cero utilizando un enfoque de prueba primero.

El tío Bob pesa en con lo siguiente:

  

¿Cuándo se rediseña la estrategia correcta?

     

Estoy contento de que hayas hecho esa pregunta. Aquí está la respuesta. Never.

     

Mira, hiciste el desastre, ahora límpialo.

Una opción sería escribir pruebas de unidad para cubrir la aplicación existente y luego comenzar a refactorizarla poco a poco, utilizando las pruebas de unidad para asegurarse de que todo funciona como antes.

En un mundo ideal, ya tendrías pruebas unitarias para el programa, pero dadas tus comentarios sobre la calidad de la aplicación supongo que no ...

Ningún documento, ningún escritor original, ningún caso de prueba y un montón de errores restantes.

No he tenido mucha suerte con pequeños cambios incrementales cuando el código que heredé es realmente malo. En teoría, el pequeño enfoque incremental suena bien, pero en la práctica, todo lo que termina es una aplicación mejor, pero aún mal diseñada, que todos piensan que ahora es TU diseño. Cuando las cosas se rompen, la gente ya no cree que sea por el código anterior, ahora es TU culpa. Por lo tanto, no usaría la palabra rediseño, refactoría o cualquier otra cosa que implique a un tipo de administrador que está cambiando las cosas a su manera a menos que realmente lo hiciera a mi manera. De lo contrario, aunque hayas solucionado docenas de problemas, los problemas que aún existían (pero no se descubrieron) ahora se atribuirán a tu reproceso. Y tenga la seguridad de que si el código es incorrecto, entonces sus correcciones descubrirán muchos más errores que simplemente se ignoraron antes porque el código era tan malo para empezar.

Si realmente sabes cómo desarrollar sistemas de software, haré un rediseño de todo el sistema. Si no REALMENTE sabe cómo diseñar el software BUENO, entonces diría que se apegue a los pequeños cambios incrementales, ya que de lo contrario podría terminar con un código base tan malo como el original.

Un error que a menudo se comete al rediseñar es que las personas ignoran el código base original. Sin embargo, el rediseño no tiene por qué significar ignorar totalmente el código antiguo. El código antiguo aún tenía que hacer lo que su código nuevo tiene que hacer, por lo que en muchos casos los pasos que necesita ya están en el código anterior. Copiar y pegar y luego ajustar las maravillas al rediseñar los sistemas. Descubrí que, en muchos casos, el rediseño y la reescritura de una aplicación y el robo de fragmentos del código original es mucho más rápido y mucho más confiable que los pequeños cambios incrementales.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top