2010-09-09 18 views
5

duplicados posibles:
What should I keep in mind in order to refactor huge code base?
When is it good (if ever) to scrap production code and start over?¿Cómo refactorizar el código heredado de manera efectiva y eficiente?

Actualmente estoy trabajando con algunos archivos de código fuente legado. Tienen bastantes problemas porque fueron escritos por un experto en bases de datos que no sabe mucho sobre Java. Por ejemplo,

  1. Los campos en las clases son públicos. Sin getters y setters.
  2. Utilice tipos brutos, no tipos parametrizados.
  3. Utilice static innecesariamente.
  4. Nombres de método super largo.
  5. Los métodos necesitan demasiados parámetros.
  6. Repita con frecuencia.

Quiero modificarlos para que estén más orientados a objetos. ¿Cuáles son algunas de las mejores prácticas y enfoques efectivos/eficientes?

+1

posible duplicado de [¿Qué debo tener en cuenta para refactorizar la enorme base de códigos?] (Http://stackoverflow.com/questions/871238), [¿Cómo puedo refactorizar clases estrechamente acopladas?] (Http: //stackoverflow.com/questions/794485/how-to-refactor-tightly-coupled-classes), [¿Cuándo es bueno (si es que hay alguna) eliminar el código de producción y empezar de nuevo?] (http://stackoverflow.com/ questions/144734), [Refactorización de código en mal diseño del sistema] (http://stackoverflow.com/questions/3618357), etc. Todo en [refactoring] (http: // stackoverflow.com/questions/tagged/refactoring) etiqueta. – BalusC

+0

"Tienen bastantes problemas porque fueron escritos por un experto en bases de datos que no sabe mucho sobre Java". Por lo general, es mejor que al revés, al menos en lo que respecta al rendimiento. – Thilo

Respuesta

8

Lea "Working Effectively with Legacy Code" por Michael Feathers. Gran libro, y obviamente será mucho más detallado que las respuestas aquí. Tiene muchas técnicas para manejar las cosas con sensatez.

Parece que ha identificado una serie de problemas, que es una gran parte del problema. Muchos de ellos suenan como que se pueden arreglar con relativa facilidad: su diseño y arquitectura en general son más difíciles de hacer, por supuesto.

¿Ya existen pruebas unitarias o las va a agregar también?

+0

No hay pruebas de unidades todavía. Probablemente escribiré algunos guiones de prueba en el futuro. – zihaoyu

+3

Intente escribir algunas pruebas antes de realizar cambios en el código, aunque es posible que tenga que refactorizar primero sin una red, como se describe en este libro altamente recomendado. –

1

Eclipse debería ser capaz de cuidar el n. ° 1 y ayudarlo a abrirse camino entre muchos otros.

En cuanto a la conversión de código OO pobre a un buen código OO es increíblemente difícil. A menudo parece más fácil reescribirlo desde cero.

Tiendo a ir de abajo hacia arriba. Como estoy trabajando en una sección pequeña, reconoceré un conjunto de datos que pertenecen juntos como grupo y haré un buen objeto que reemplace ese código sin cambiar nada más - Cambios muy pequeños con pruebas constantes entre cada cambio .

Esto hace un diseño mediocre en el mejor de los casos, pero sinceramente no sé si puede pasar de no OO a buen OO en un proyecto grande sin diseccionar el programa original, entendiéndolo y usándolo como plantilla para el reescriba y pocos proyectos lo permitan (aunque podría ser más rápido, rara vez o nunca será capaz de convencer a la gerencia de ese hecho)

0

¿Cuál es el problema con que no tenga getters y setters? Sugeriría refactorizarlos solo cuando necesites agregar getters o setters no triviales (por ejemplo, con validación).

El resto suena como que necesita identificar grupos de valores y crear nuevos tipos sosteniéndolos, por lo que en lugar de pasar un String name, String address, int yearOfBirth, String [] accountNames, int [] equilibra pasaría un Cliente alrededor, que a su vez tendría una cuenta [].

IDEA Ultimate Edition tiene un detector de duplicación de código que es muy buena (sólo le falta un botón 'solución sugerida'!), Y hay CPD etc.

me gustaría sugerir que en una gran base de código legado que podría pierde el código de refactorización del tiempo solo para descubrir que no se usó de todos modos. Describí algunos pasos para eliminar el código no utilizado: http://rickyclarkson.blogspot.com/2009/12/deleting-code-what-first.html

+0

El problema de no tener getters y setters es que la implementación interna está expuesta al mundo exterior. No podrá cambiar la implementación en el futuro sin romper la compatibilidad. Por lo tanto, el cambio "menor" puede requerir la fijación de algunas otras clases ... –

+0

Cambiar otras clases está bien, al menos si este código no es parte de una API pública. Incluso si es parte de una API pública, no es necesariamente un gran problema. –

5

Antes de comenzar, cree un conjunto de pruebas de regresión a nivel de sistema para la aplicación. Necesitas esto para que puedas verificar que tus cambios no rompan cosas.

Para realizar la refactorización, desea utilizar una combinación de un IDE adecuado y una herramienta de búsqueda de texto (por ejemplo, grep). Use la herramienta de búsqueda de texto para buscar las ocurrencias de los "síndromes" que desea corregir, luego use el IDE (y sus capacidades de refactorización integradas) para arreglar las instancias ... una a la vez.

Por ejemplo, Eclipse le permite cambiar el nombre de un método o clase, o generar getters y setters. Entonces, curaría un atributo 'público' por:

  1. Cambie el atributo a privado.
  2. Genera los métodos getter y setter.
  3. Guarde el archivo.
  4. Revise todos los errores de compilación de Java resultantes del hecho de que el atributo ahora es privado, y cambie para usar el getter o el setter según corresponda.

Este enfoque le dará la fruta más baja. Los problemas de diseño más fundamentales son más difíciles y pueden ser imposibles de solucionar sin una reestructuración fundamental de la aplicación. Las capacidades de refactorización le ayudarán a ejecutar dichos cambios, pero decidir qué hacer depende de usted.

Finalmente, mi consejo es que no sea demasiado ambicioso. Busque mejoras graduales y esté preparado para trazar la línea cuando el código sea "lo suficientemente bueno". No alcanzarás la perfección ... ni siquiera si comienzas de cero, así que no pongas tus expectativas en alto.

+0

+1 para la prueba de regresión completa! –

+1

Los 4 pasos enumerados se podrían realizar más simplemente con la refactorización de ** Encapsulate Field ** de Eclipse. –

+0

@Stephen C +1 para el conjunto de pruebas de regresión – sfrj

1

El punto es riesgo Creo.

El código feo es feo, pero podría funcionar, se ha probado y corregido. Si se cambia el código ejecutable, correrá el riesgo. entonces la prueba es crítica.

  • Puede refactorizar el código relacionado cuando tiene que corregir, como una solución de conservadurismo.

Tal vez el primer reto es persuadir a su administrador :)

0

¿Cuántos de esos "problemas" son problemas reales y no sólo las cuestiones de estilo? De esta lista, el único problema "real" que puedo ver es "Repítete con frecuencia", y eso es más un problema de mantenimiento continuo que debería resolverse durante el mantenimiento normal del código cuando alguien va a cambiar el código de todos modos.

0

Quiero modificarlos para que estén más orientados a objetos.

Orientación de objetos: no debe ser su único objetivo al refaccionar. La pregunta que debe hacerse es cuál es el ROI esperado (mejor calidad, mejoras más fáciles, mejor uso compartido de este código en un equipo). Un ROI no es solo palabras, debe estar preparado para medir con números el retorno de la inversión (incluso las mejoras de calidad, por ejemplo). Debe tener en cuenta la duración de vida de sus productos al estimar el ROI.

También debe preguntarse cuál es el tamaño del código que depende del código que desea refactorizar. Refactorizar una biblioteca podría ser fácil, pero podría generar muchos cambios en los códigos fuente que dependen de esta biblioteca, un trabajo mucho más extenso que la simple refacturación de la biblioteca.

Antes de tocar cualquier código, debe estimar el trabajo total que debe realizarse para terminar de refactorizar el código y el código dependiente. Debe estimar una reescritura total del código, una reescritura parcial o simplemente una reescritura interna sin tocar las API.

Con los costos y las devoluciones, puede decidir si vale la pena el esfuerzo de refactorizar su código.

2

¿El código es malo o también perjudica la experiencia del usuario? Refactorizar continuamente es una buena idea, pero no debe ser un objetivo en sí mismo. Debería mejorar la aplicación en términos de interacción del usuario, mantenibilidad, estabilidad, rendimiento, etc.

Es por eso que no soy muy aficionado a la refactorización enorme solo para mejorar la calidad del código. En cambio, refactorice el código con el que trabaja.

Mientras se trabaja con un sistema heredado desde hace varios años, he encontrado personalmente que:

  1. crear para sí mismo una visión de cómo desea que el código después de que haya terminado. Debería ser alcanzable, contener una lista de cambios tecnológicos, cambios generales de arquitectura. También puede ser una buena idea dar una prioridad aproximada a las clases que son más importantes para cambiar. Hace unos años, carecíamos de esa visión, y si bien refactoramos mucho, la calidad del código apenas mejoró.
  2. Ahora, debe restringir su refactorización a aquellos que le hacen llegar a su visión. No caigas en la trampa de hacer lo que parece bueno en este momento.
  3. Enfóquese en un componente en particular, y hágalo mejor. Luego pasa al siguiente. Es tentador hacer grandes cambios que afectan a todo el sistema, pero en verdad introducirás más problemas de los que resuelves.
  4. Integración de escritura pruebas de regresión. Es decir, algunas pruebas grandes que prueban mucha funcionalidad. No es óptimo, pero es lo mejor que puedes hacer. Escribir pruebas de unidades para cada clase en su sistema anterior puede terminar en una pérdida de tiempo porque no está diseñado para ser probado de todos modos y desea rediseñar la mitad de las clases.
  5. Acepte que llevará tiempo.
Cuestiones relacionadas