2009-03-14 26 views
15

Todos hemos oído hablar de premature optimization, pero ¿qué opina sobre la refactorización prematura? ¿Hay algo así en tu opinión? Esto es a lo que me refiero.refactorización prematura?

Primero, leer el trabajo seminal de Martin Fowler "Refactoring" cambió literalmente mi vida en lo que respecta a la programación.

Una cosa que he notado, sin embargo, es que si empiezo a refactorizar una clase o framework demasiado rápido, a veces me encuentro codificado en una esquina por así decirlo. Ahora, sospecho que el problema no es realmente la refactorización per se, sino las decisiones/suposiciones de diseño prematuros/deficientes.

¿Cuáles son sus pensamientos, ideas u opiniones sobre este tema? ¿Tiene algún consejo o antipatrón común relacionado con este problema?

EDIT:

De la lectura de sus respuestas y reflexionar sobre esta cuestión más, creo que me he dado cuenta de que mi problema en este caso es realmente un problema de "diseño prematura" y no necesariamente " refactorización prematura ". He sido culpable de asumir un diseño y una refactorización en esa dirección al principio del proceso de codificación. Un poco de paciencia de mi parte para mantener un nivel de agnosticismo en el diseño y centrarme en la refactorización hacia un código limpio me impediría dirigirme hacia estos senderos de diseño de conejos.

Respuesta

10

De hecho, creo lo contrario.

Cuanto antes empiece a pensar si su diseño necesita una refabricación, mejor. Refactor constantemente, por lo que nunca es un gran problema.

También he descubierto que cuanto más refactorizo ​​desde el principio, mejor me he dado a la hora de escribir código de manera más limpia. Tiendo a crear menos métodos grandes, y tengo menos problemas.

Sin embargo, si se encuentra a usted mismo "refaccionando" en una esquina, esperaría que sea más una cuestión de falta de diseño inicial o falta de planificación para el alcance de uso de una clase. Intente escribir cómo desea usar la clase o el marco antes de comenzar a escribir el código, ya que puede ayudarlo a evitarlo. También creo que esta es una de las ventajas de probar el diseño impulsado: te ayuda a forzarte a utilizar el objeto antes de que esté escrito.

Recuerde, la refabricación técnica NUNCA debe encerrarlo en una esquina, se trata de volver a trabajar las partes internas sin cambiar la forma en que se utiliza una clase. Si te atrapa por refactorización, significa que tu diseño inicial fue defectuoso.

Lo más probable es que, con el tiempo, este problema sea cada vez mejor. Su diseño de clase y marco probablemente terminará siendo más flexible.

+0

Gracias a todos por su contribución. Aprendí mucho de su visión colectiva. Seleccioné esto como la "respuesta" porque creo que coincide con mi situación actual; sin dudas, un hecho que sería difícil de descifrar para nadie más que para mí. – Swim

1

Creo que cualquier proyecto "1.0" es susceptible a este tipo de ... llamémoslo "diseño iterativo". Si no tiene una especificación clara antes de comenzar a diseñar sus objetos, probablemente pensará en muchos diseños y enfoques de problemas.

Por lo tanto, creo que superar este problema específico es diseñar claramente las cosas antes de comenzar a escribir el código.

1

Existen un par de soluciones prometedoras para este tipo de problema, dependiendo de la situación.

Si el problema es que decide que algo se puede optimizar de cierta manera y extrae un método o algo y se da cuenta de que debido a esa decisión, se le obliga a codificar todo lo demás de una manera complicada, el problema es probablemente que no pensaste lo suficiente en el proceso de diseño. Si hubiera existido una especificación bien escrita y planificada, usted habría sabido de antemano este problema (a menos que no haya leído la especificación, pero ese es otro problema :))

Dependiendo de la situación, el prototipado rápido puede también abordan este problema, ya que tendrá una mejor idea de estos detalles de implementación cuando comience a trabajar en el producto real.

+0

No hay sugerencia en la pregunta de que el esfuerzo de diseño sea laxo. La pregunta también descarta la optimización pre-madura, que es una bola de cera diferente. – AnthonyWJones

5

Creo que es posible refactorizar demasiado pronto.

En el extremo tuercas y tornillos de diseño es el código en sí. Esta etapa final del diseño entra en vigencia a medida que usted codifica, a veces tendrá fallas y lo verá a medida que el código evolucione. Si se refactoriza demasiado pronto, es más difícil cambiar el diseño defectuoso.

Por ejemplo, es mucho más fácil eliminar una sola función cuando se da cuenta de que es basura o va en la dirección incorrecta que eliminar una función bien formada y las funciones que utiliza y las funciones que utilizan, etc. ., al tiempo que garantiza que no está rompiendo algo más que era parte del refactor.

Podría decirse que tal vez debería haber dedicado más tiempo al diseño, pero un elemento clave en un proceso ágil es que la codificación es parte del proceso de diseño y en la mayoría de los casos, después de poner un esfuerzo razonable en el diseño, es mejor simplemente seguir adelante con eso.

Editar En respuesta a los comentarios: -

El diseño no se realiza hasta que haya código escrito. No podemos resolver todos los problemas en el diseño de precodificación, todo el punto detrás de Agile es que la codificación es solución de problemas. Si el diseño sin código resolvió todos los problemas por adelantado antes de la codificación, no habría necesidad de re factor, simplemente convertiríamos el diseño en código bien procesado en un solo paso.

¿Alguien recuerda los métodos de diseño estructurado de finales de los 80 y principios de los 90, los que resolvieron todos los problemas en diagramas inteligentes antes de escribir una línea de código?

+0

Veo su punto, pero la refacturación no debería cambiar su diseño ... Un diseño defectuoso es defectuoso ya sea una función de 500 líneas de largo o una función de 20 líneas para llamar a otras rutinas. Encuentro que la refactorización ayuda a cristalizar el diseño en sí mismo, por lo que puede decir lo que requiere el mundo exterior frente a la basura. –

+0

Pero quizás sea solo mi estilo de trabajo personal. +1 por hacerme pensar al respecto, aunque :) –

+0

Sí. Pero tome un ejemplo: comienza a escribir su código y luego descubre que tiene una gran función. Si no lo refactoriza entonces, será casi imposible escribir pruebas limpias para él, y mucho menos hacer que otras personas entiendan por qué está limpio. –

1

Creo firmemente en la refacturación constante. No hay ninguna razón para esperar hasta un momento específico para comenzar la refactorización.

Cada vez que vea algo que debería hacerse mejor, Refactor.

Solo téngalo en cuenta. Conozco a un desarrollador (un genio puro) que refactoriza tanto (es tan inteligente que siempre puede encontrar una mejor manera) que nunca termina un proyecto.

+0

La última oración es un gran argumento contra la refactorización constante. "Perfecto" es el enemigo del "bien". – WallTearer

1

La razón por la cual la optimización prematura es mala es que la optimización generalmente conduce a un diseño peor. A diferencia de la refactorización, que conduce a un diseño mejor y más limpio, si se hace de forma reflexiva y correcta. Lo que aprendí para ser útil para analizar la utilidad de una refactorización fue primero mirar nuestro diagrama UML para visualizar el cambio y luego escribir el código-doc (por ejemplo, Javadoc) para la clase primero y agregar trozos antes que cualquier código real.Por supuesto, la experiencia ayuda mucho con eso, en caso de duda, pregúntele a su arquitecto favorito;)

7

Todos hemos oído hablar de Optimización prematura, pero ¿qué opina de Refactorización prematura? ¿Hay algo así en tu opinión?

Sí, la hay. Refactorizar es una forma de que paga la deuda técnica que se ha acumulado durante la vida de su proceso de desarrollo. Sin embargo, la mera acumulación de deuda técnica no es necesariamente algo malo.

Para ver por qué, imagine que está escribiendo un software de análisis de impuestos para el IRS. De repente, se introducen nuevas regulaciones en el último minuto que rompen varias de sus suposiciones originales. Aunque diseñó bien, su modelo de dominio se ha desplazado fundamentalmente desde sus pies en al menos un lugar importante. Es el 14 de abril, y el proyecto debe ponerse en marcha mañana, venga al infierno o en alta mar. ¿Qué haces?

  • Si implementa una solución de tuercas y pernos a costa de parte de la deuda técnica moderada, el sistema se volverá más rígida y menos capaz de soportar otra ronda de estos cambios. Pero el sitio puede activarse y continuar, y no habrá riesgo de retrasos en la entrega; confía en que puede hacer los cambios necesarios.
  • Por otro lado, si se toma el tiempo para refabricar la solución para que ahora admita el nuevo diseño de una manera más sofisticada y flexible, no tendrá problemas para adaptarse a cambios futuros. Pero corre el riesgo de que el producto estrella de su empresa se enfrente al reloj; no está seguro si el rediseño tardará más que hoy.

En este caso, la primera opción es la mejor opción. Suponiendo que tiene poca deuda técnica previa, vale la pena tomar sus terrones ahora y pagarlo más tarde. Esta es, por supuesto, una decisión comercial, y no de diseño.

+1

Fowler incluso afirma que la semana anterior a la fecha límite no es el momento para emprender nada más que una pequeña refactorización. –

+1

La refabricación se trata de cambiar las partes internas de su código sin alterar la interfaz externa y la API: la refactorización "pura" no debería tener ningún efecto. El diseño cambia debajo de ti y reelaborar tu código para que coincida con un nuevo diseño es una bestia diferente: eso es un rediseño. –

+0

Por otro lado, por ejemplo, si estoy trabajando en una función, y se vuelve demasiado grande, siempre la refactorizaré en ese momento si es posible. De lo contrario, es imposible probarlo a fondo, etc. –

3

La refacturación prematura se está refactorizando sin pruebas unitarias. En ese momento, simplemente no está listo para una refactorización. Primero haga algunas pruebas unitarias y luego comience a pensar en refactorizar. De lo contrario, dañarás (quizás) el proyecto más que ayudar.

+0

La falta de pruebas unitarias es una condición suficiente para diagnosticar la refactoración como prematura, pero no es una condición necesaria. Incluso con pruebas unitarias, hay circunstancias en que la refacturación es prematura. Entonces el axioma "es" que tienes en negrita es un poco engañoso para mí. –