software guru espaƱol book refactoring

guru - refactoring translate



Refactor sin piedad o construir uno para tirar? (14)

Creo que su sistema de control de versiones juega un papel importante aquí. Si ejecuta un sistema de control de versiones distribuidas con una bifurcación fácil (git, mercurial, en estos días), podrá prototipar más fácilmente y refactorizar más fácilmente, todo mientras tiene una copia de trabajo válida. Cualquier otra cosa requiere mucha más disciplina.

Cuando se usa un nuevo concepto de sistema o nueva tecnología, uno tiene que construir un sistema para tirar, ya que incluso la mejor planificación no es tan omnisciente como para hacerlo bien la primera vez. Por lo tanto, planea tirar uno; lo harás, de todos modos.

- Fred Brooks, The Mythical Man-Month [Énfasis mío]

Construye uno para tirar. Eso es lo que me dijeron. Luego me dijeron que todos somos ágiles ahora, por lo que deberíamos refactorizar sin piedad . ¿Lo que da?

¿ Siempre es mejor refactorizar mi camino para salir del problema? Si no es así, ¿alguien puede sugerir una regla empírica que me ayude a decidir cuándo cumplirla y cuándo renunciar y empezar de nuevo?


Tirar temprano, refactorizar más tarde

Tirarlo está bien para sistemas pequeños, pero si el tamaño del sistema es enorme, simplemente no tiene los recursos para hacerlo.

Sin embargo, podría crear un pequeño proyecto piloto que implemente solo las características esenciales del proyecto real. Después de algunos intentos de prueba y error, de aprender y tirar cosas, terminas con un núcleo sólido y una mejor comprensión del proyecto real. Luego, permite que crezca el tamaño del proyecto al agregar todas las características necesarias. Pero una vez que llegas allí, de ninguna manera puedes tirar el núcleo. Solo refactorización.


Crearé un prototipo cuando intente resolver un nuevo problema o funcionalidad. Después de eso, lo reconstruiré en base a lo que aprendí. En realidad, eso se parece mucho a refactorizar ... ¿qué? Tal vez es lo mismo? Hmmm ...


Creo que tirar uno es a veces el mejor camino a seguir, pero puede doler. Una cosa que he encontrado que funciona bien es tirar uno, pero elige bien tu tecnología.

Por ejemplo, escribí una gran base de código en Ruby on Rails, y en los últimos 2 o 3 años, RoR ha avanzado mucho. También tomé algunas decisiones en arquitectura que debían corregirse. Entonces, estoy tirando uno y construyendo uno nuevo desde cero. Sin embargo, todavía puedo usar un 70-80% más o menos de mi código anterior, ya que todavía estoy escribiendo en Ruby and Rails.

El principal factor que ha ayudado con eso es que Rails te obliga a escribir un código bien estructurado con separación de lógica de negocios y capas de presentación. No lo entendí perfecto la primera vez, pero como todo está bastante bien separado y SECO, portar el código a Rails v2.1, volver a diseñar las áreas problemáticas y volver a escribir algunas características de "problema" ha sido una experiencia bastante libre de dolor.

Por lo tanto, al elegir una gran tecnología desde el principio, pude tirar una, pero aún así llevo conmigo el 70-80% de las cosas viejas que todavía funcionan.


Cuando se habla de Agile, se pueden hacer ambas cosas, pero de forma general, se harán picos (prototipos) solo para tratar problemas específicos, aprender sobre ellos y poder hacer mejores estimaciones. Bótelo cuando está haciendo un simple pico y refactorizando cuando realmente está codificando la aplicación.

Saludos cordiales


Diferentes situaciones requieren diferentes enfoques. Personalmente, prefiero refactorizar a un mejor diseño siempre que sea posible. Refactorizar conduce a menos errores que una reescritura.

Pero, incluso si planea tirar uno, sigue siendo una buena idea escribir un montón de pruebas de aceptación para asegurarse de que su segunda versión esté en el camino correcto. Luego, puede migrar hacia la siguiente versión pieza por pieza, a la vez que garantiza que su funcionalidad no cambie desde la perspectiva del usuario. Suena un poco como refactorizar, solo un poco más descuidado, supongo.


En un ensayo posterior en The Mythical Man Month, Brooks advierte que ha descubierto que si de hecho planea tirar 1, ¡acabará tirando 2!

Yo personalmente vi esto suceder en la vida real; asignamos una versión 1 del proyecto como un lanzamiento rápido a un programador mediocre, porque "planeamos descartarlo más tarde, lo haremos de todos modos". Terminamos teniendo que reescribirlo para la versión 2, pero ese fue descartado también. Nunca vi la versión 3: la empresa cerró.

Creo que cuando Brooks dice "planeas tirar uno, lo harás de todos modos", se parece más a la afirmación de que "el número de errores que quedan por encontrar es ''n + 1''". Es decir, es una declaración de ha-ha-solo-serio sobre la ley de Murphy, en lugar de consejos prácticos. Las lecciones que debemos extraer son que los prototipos son valiosos, que la buena redacción se está reescribiendo y que no se teme abandonar algo que no funciona.

Sin embargo, tiene que venir a juicio porque, como Joel Spolsky ha mencionado en varios ensayos, la opción de tirar y empezar de nuevo es tentador porque el código es más fácil de escribir que de leer y más divertido de escribir que de mantener. , entonces tu inclinación natural siempre será comenzar de nuevo incluso cuando eso no sea lo mejor que puedes hacer.


Llega un momento en que la refactorización es una pérdida de tiempo. Solo tienes que comenzar de nuevo desde cero. Si mantiene su diseño bastante flexible y reconoce que aún no sabe todo, no tendrá que tirar nada. Una clase puede volverse redundante, por supuesto, pero no descartarás un sistema completo.

Tener un diseño flexible es necesario para poder refactorizar correctamente. No tener un diseño o un diseño rígido significa que terminará tirando algo, ya sea porque no puede refactorizar, o porque la refactorización constante degrada el mantenimiento de su base de códigos. Pocos humanos son lo suficientemente meticulosos y disciplinados para poder completar una larga secuencia de refactorizaciones menores para mantener la integridad. ¡A menos que tengas un equipo de estrellas, esta degradación sucederá!

TL; DR: Usted puede refactorizarse para salir de la mayoría de los problemas. Ocasionalmente, sin embargo, no podrá refactorizar más allá de algunos elementos de diseño. Cuando eso sucede, es hora de comenzar de nuevo, aunque es de esperar que pueda reutilizar algunos de los componentes que tiene instalados.


Si eres despiadado, el resultado final de la refactorización será bastante similar al que obtendrías si reconstruyes desde cero, pero no te habrás quedado atrapado en un sistema que no funciona durante el proceso.


Si está realizando un desarrollo basado en pruebas, puede refactorizar su salida de casi cualquier problema. Cambié las principales decisiones de diseño sin muchos problemas y rescaté bases de código de hace una década.

La única excepción es cuando descubre que su arquitectura está completamente equivocada de principio a fin. Por ejemplo, si escribiste tu aplicación usando hilos, pero descubriste que querías un montón de máquinas de estado asíncronas. En ese momento, adelante y tire el primer borrador.


Uno de los puntos centrales de The Mythical Man Month fue que la parte más difícil del desarrollo de software es descubrir qué decir, no cómo decirlo.

La forma en que lo he interpretado recientemente es que el mayor valor que obtiene del primer borrador son los requisitos que ha reunido y conservado en forma de pruebas. Si tiene cuidado de no probar cosas que no son realmente requisitos del sistema, puede refactorizarse para salir de cualquier desorden.

Mientras no te codifiques en una trampa donde tienes que comenzar a tirar pruebas, puedes arrojar todo el código que quieras sin perder una cantidad significativa de trabajo real.


Mi consejo general aquí es refactorizar un sistema existente de sus malos diseños a un sistema con mejores diseños. Esto mantiene el sistema y le permite ser desplegado en todo momento. Si comienza desde cero, puede pasar un tiempo hasta que pueda implementarse o nunca.

Si está hablando simplemente de escribir un código nuevo donde no hay un sistema existente, con frecuencia es una buena idea escribir un poco de código, como quiera, luego descartarlo ya que nunca fue implementado y comenzar de nuevo ( usando TDD).


Como gerente de desarrollo en esta organización, no estoy "autorizado" a escribir código de producción.

Yo (ab) uso esa regla para anular el código rápido y sucio de la prueba de concepto que aborda uno u otro punto, luego lo controlo en el control de la fuente y le señalo un "apropiado" y digo "Así es como es hecho, ahora hazlo bien ".

Eso es lo más cerca que podemos llegar de "uno para tirar" aquí, y probablemente me tome un par de horas máx. Tocar juntos. Dedicar tiempo a cosas como el manejo de errores, la verificación de límites y todos los demás bits que hacen un buen código sería una pérdida de tiempo para este tipo de trabajo, pero significa que los tipos a los que se les paga para escribir código de producción pueden gastar su tiempo. tiempo escribiendo código de producción y no tiene excusas como "es solo un prototipo" cuando se trata de tiempo de revisión de código.

Construir uno para tirar se usa a menudo como excusa para no hacer el trabajo correctamente. Eso significa que en realidad no se encuentra con suficientes problemas en el proceso como para aprender lo suficiente como para aprovechar el tiempo de otra persona. Y hacerlo correctamente, solo tirarlo, es aún más derrochador.

Como varias personas han dicho anteriormente, la característica más importante en cualquier software es que se envía. Con esto en mente, construiría "uno para hacer que la gente me pague" en cualquier momento, y mi implacabilidad en términos de refactorización es permitir solo lo suficiente para obtener un producto que funcione y pueda mantenerse razonablemente.


Es fácil construir uno para tirar en cualquier sistema de gestión de configuración que soporte el concepto de una sucursal. Si está introduciendo un cambio de diseño radical en un sistema existente que está en el campo y es la fuente de su sueldo; usted maldita mejor rama; prototipo; y tíralo si no funciona.

La refacturación de un gran sistema de vacas de efectivo heredado a menudo conduce a una piratería clásica y anticuada. Refactorizar suena mucho mejor que piratear, supongo.