2008-12-01 23 views
22

Actualmente estoy trabajando en un fragmento de código donde tanto la lógica como el acceso a los datos están presentes en las clases de la GUI. Obviamente, me gustaría mejorar en esta situación.Estrategia para la refacturación a gran escala

La estructura actual es básicamente:

  • gran bola de barro

El objetivo final es lograr una estructura DDD-como:

  • DAL
  • modelo de dominio
  • Capa de servicio
  • Presentación modelo
  • GUI

Así que, ¿cómo atacar el problema?

  • Big bang
    • definir la estructura para el estado final y empuje código a su casa definitiva.
  • Divide y vencerás
    • tratar de separar la gran bola de barro en dos piezas. Repita hasta que esté hecho ...
  • estrangular

Respuesta

15

Nunca intente "Big Bang". Casi siempre te golpea en la cara, ya que es una medida desesperada y de alto riesgo cuando todo lo demás ha fallado.

Dividir y conquistar: Esto funciona bien ... si su mundo tiene solo dos lados. En el software real, tiene que conquistar tantos frentes al mismo tiempo, que rara vez puede darse el lujo de vivir en una fantasía de blanco y negro.

Supongo que he estado utilizando algo así como "Estrangular" la mayor parte de mi carrera profesional: cambiar gradualmente el código viejo y malo por un nuevo código brillante. Aquí está mi receta:

Comience en alguna parte, en realidad no importa dónde. Escriba algunas pruebas unitarias para ver cómo se comporta realmente el código. Averigüe con qué frecuencia hace lo que cree que hace y con qué frecuencia no lo hace. Use su IDE para refactorizar el código para que pueda probarlo.

Después del primer día, adivina si has comenzado en el lugar correcto para desarmar a este monstruo. Si es así, continúa. Si no, busca un lugar nuevo y comienza de nuevo.

Ventajas de esta estrategia: funciona en pequeños pasos, por lo que el riesgo puede mantenerse bajo control y si algo se rompe, si tiene que estar en el código en el que ha estado trabajando la semana pasada.

Desventaja: Lleva mucho tiempo y se sentirá frustrado porque a menudo, el progreso parecerá tan lento hasta que aparezca el "nudo" y, de repente, todo comienza a caer en su lugar como por arte de magia.

0

es una reescritura total de una opción? En mi experiencia, reescribir desde cero a menudo puede ser más eficiente que tratar de limpiar el desastre existente. Todavía conservas partes del código existente pero en un nuevo contexto. Y lo mismo aplica para la GUI y la base de datos si tiene una. Reescribe desde cero y lleva contigo lo que puedes usar.

1

Depende de si tiene que tener siempre un estado de trabajo, para que pueda corregir errores y desplegar cada vez que sea necesario, entonces Devide and Conquer sería una buena solución. Si puede mantener el código anterior, mientras trabaja en uno nuevo (y tiene la disciplina para aplicar correcciones de errores a ambas bases de código) una reescritura puede ser una mejor solución.

6

Nunca había oído hablar del término 'Aplicación de Estrangulador' - Me gusta. Siempre que sea posible, este sería siempre un buen enfoque, ciertamente minimiza el riesgo y es bastante pragmático, fragmentando el edificio grande pieza por pieza.

Cuando eso no funciona en mi experiencia es cuando se necesitan cambios razonablemente significativos de inmediato, cambios que requerirán un poco de refactorización (o una gran cantidad de piratería). En esa situación, a menudo descubrí que los cambios que debía hacer estaban en el corazón de la gran bola de barro y no había otra opción que ensuciarme: incluso lo que debería haber sido mantenimiento estándar o cambios menores de mejora eran simplemente horribles y refactor importante fue la mejor opción.

Para esos casos, yo iría con dividir y conquistar - el primer objetivo que siempre pretendo es la capacidad de prueba, una vez que tiene que todo el resto es mucho más fácil. De hecho, ese es a menudo uno de los principales factores que tengo para refactorizar lejos de la gran bola de lodo: ese tipo de código a menudo es casi imposible de probar, con suerte hay ejemplos de entradas y salidas de IU, pero a veces incluso eso falta .

Así que cuando me enfrento al código donde todo está agrupado en la UI, generalmente empiezo por factorizar unidades discretas de funcionalidad en clases y métodos, y luego presiono esas partes de código en un dominio o capa de servicio. Hacerlo poco a poco reduce en gran medida las posibilidades de romper algo y facilita la localización del código de corte cuando las cosas van mal.

Ejecuta los casos de prueba que tengas disponibles al final de cada cambio y asegúrate de que sigues cumpliendo con algún tipo de línea base.

Si escribe buenas pruebas unitarias sobre la marcha, puede comenzar a reducir la escala del problema y he descubierto que pronto es práctico adoptar el enfoque de estrangulamiento, con pruebas unitarias decentes o al menos el marco adecuado para permitir la escritura de pruebas de unidades decentes se vuelve mucho más práctico para reemplazar gradualmente partes de la funcionalidad.

1

Si por refactorización, quiere decir mejorar el código sin modificar la funcionalidad, comenzaría por crear una línea base de pruebas de regresión automática. Hay muchas herramientas para ayudar con esto. Yo uso TestComlete aunque hay buenas alternativas baratas.

Después de haber establecido una línea base de prueba de regresión, personalmente iría con divide y vencerás, ya que, según mi experiencia, es la que más posibilidades tiene de tener éxito. Una vez que tenga una línea de base de prueba, importa menos qué enfoque elija.

-1

Comenzar con una arquitectura nueva y limpia y mover las partes antiguas del código en esta nueva arquitectura pieza por pieza y refactorizarla para adaptarse al nuevo arco sería una buena opción. Creo que un enfoque ascendente cuando mueva las funciones sería bueno.

1

Para mí depende de la situación.

Si es un proyecto muy pequeño, estaría tentado de volver a escribirlo desde cero ... sin embargo, a menudo no tiene ese lujo.

De lo contrario, iría por desmenuzarlo pieza por pieza. Escribía pruebas unitarias para verificar la funcionalidad existente y usar lentamente TDD para transformar el código en un sistema elegante y bien diseñado. Dependiendo de cuánto tiempo va a durar este proceso, probablemente comenzará a parecerse a la aplicación Strangler que mencionó anteriormente.

BigBang es muy arriesgado ya que no tiene una forma fácil de verificar que el sistema actualizado haga lo mismo que el anterior.

Divide and Conquer es menos riesgoso que BigBang ... pero si es un sistema lo suficientemente grande, puede terminar siendo tan problemático como BigBang.

1

Big bang/re-diseño de Big/reescribir el SW ... o cualesquiera otros nombres no trabajo para un SW vivo. Las razones son:

  • que todavía tienen que soportar el SO existente con (probablemente) los mismos recursos que tiene.

  • Probablemente no tenga los requisitos para volver a escribir. Su código anterior tiene todos los requisitos integrados. Ninguno de sus ingenieros conoce todos los dominios SW y todos los requisitos.

  • Reescribir llevará tiempo. Al final de este tiempo, encontrará que el SW existente ha cambiado para admitir cosas que se requerían durante este tiempo. su nuevo SW realmente se separará del original y se necesitará combinar (lo que también llevará tiempo).

Cuestiones relacionadas