Pregunta

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

La estructura actual es básicamente:

  • Gran bola de barro

El objetivo final es lograr una estructura similar a DDD:

  • DAL
  • Modelo de dominio
  • Capa de servicio
  • Modelo de presentación
  • GUI

Entonces, ¿cómo atacarías el problema?

  • Big Bang
    • Defina la estructura para el estado final y envíe el código a su hogar definitivo.
  • Divide y vencerás
    • Intenta separar la gran bola de barro en dos pedazos. Repita hasta que termine ...
  • Estrangulamiento
¿Fue útil?

Solución

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

Divide y vencerás: esto funciona bien ... si tu mundo tiene solo dos lados. En el software real, tienes que conquistar tantos frentes al mismo tiempo que rara vez puedes permitirte vivir en una fantasía en blanco y negro.

Creo que he estado usando algo como "Estrangulamiento" durante la mayor parte de mi carrera: transformando gradualmente el viejo código malo en un nuevo y brillante código. Aquí está mi receta:

Comience en alguna parte, realmente 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, encuentre un nuevo lugar y comience 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 te sentirás frustrado porque a menudo, el progreso parecerá muy lento hasta que el "nudo" aparece y, de repente, todo comienza a encajar como por arte de magia.

Otros consejos

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

Donde eso no funciona en mi experiencia es donde se necesitan cambios razonablemente significativos de inmediato, cambios que requerirán un poco de refactorización (o mucho pirateo). En esa situación, a menudo descubrí que los cambios que necesitaba hacer estaban en el corazón de la gran bola de lodo y no había otra opción que ensuciarnos, incluso lo que debería haber sido un mantenimiento estándar o cambios menores de mejora fueron simplemente horribles y refactor principal era la mejor opción.

Para esos casos, iría con divide y venceré: el primer objetivo que siempre busco es la capacidad de prueba, una vez que tenga que todo lo demás es mucho más fácil. De hecho, ese es a menudo uno de los principales impulsores que tengo para refactorizar lejos de la gran bola de barro & # 8211; ese tipo de código a menudo es casi imposible de comprobar, es de esperar que haya entradas y salidas de interfaz de usuario de ejemplo, pero a veces incluso eso falta.

Entonces, cuando me enfrento a un código donde todo está agrupado en la interfaz de usuario, generalmente comienzo factorizando unidades discretas de funcionalidad en clases y métodos, y luego empujando esas partes del código hacia un dominio o capa de servicio. Hacerlo poco a poco reduce en gran medida la posibilidad de romper algo y hace que sea más fácil determinar dónde estaba el código de ruptura cuando las cosas van mal.

Ejecute los casos de prueba que tenga disponibles al final de cada cambio y asegúrese de que aún cumple con algún tipo de línea de base.

Si escribe buenas pruebas unitarias a medida que avanza, puede comenzar a reducir la escala del problema y descubrí que pronto será práctico adoptar el enfoque de estrangulador, con pruebas unitarias decentes o al menos el marco adecuado para permitir al escribir pruebas unitarias decentes se vuelve mucho más práctico reemplazar gradualmente partes de la funcionalidad.

Me topé con "el Método Mikado". eso parece prometedor para atacar problemas de esta naturaleza.

http://mikadomethod.wordpress.com/

También se habla sobre el Método Mikado de & # 216; redev 2010.

http://oredev.org/2010/ sesiones / refactorizaciones a gran escala utilizando el método mikado

Big bang / Big re-design / rewriting the SW ... o cualquier otro nombre que no funcione para un SW vivo. Los motivos son:

  • Todavía necesita admitir el SW existente con (probablemente) los mismos recursos que tiene.

  • Probablemente no tenga los requisitos para reescribir. Su antiguo código 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 las cosas que se requerían durante este tiempo. su nuevo SW realmente se separará del original y será necesario fusionarlo (lo que también llevará tiempo).

Depende de si debe tener siempre un estado de funcionamiento, de modo que pueda corregir errores e implementarlos siempre 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.

Si refactorizando, quiere decir mejorar el código sin modificar la funcionalidad, comenzaría creando una línea base de prueba de regresión automatizada. Existen muchas herramientas para ayudar con esto. Utilizo TestComlete aunque existen buenas alternativas baratas.

Una vez establecida una línea base de prueba de regresión, personalmente iría con divide and conquer, ya que en mi experiencia es más probable que tenga éxito. Una vez que tenga una línea de base de prueba, no importa qué enfoque elija.

Para mí depende de la situación.

Si se trata de un proyecto muy pequeño, me vería tentado a volver a escribirlo desde cero ... sin embargo, a menudo no tienes ese lujo.

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

BigBang es muy arriesgado ya que no tiene una manera 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.

¿Es una reescritura total una opción? En mi experiencia, la reescritura desde cero a menudo puede ser más eficiente que tratar de limpiar el desorden existente. Aún conserva partes del código existente pero en un nuevo contexto. Y lo mismo ocurre con la interfaz gráfica de usuario y la base de datos si tiene una. Reescribe desde cero y lleva contigo lo que puedes usar.

Comenzar con una nueva arquitectura limpia y trasladar las viejas piezas de código a esta nueva arquitectura pieza por pieza y refactorizarlas para adaptarlas al nuevo arco sería una buena opción. Creo que un enfoque de abajo hacia arriba al mover las funciones sería bueno.

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