Arqueología de Software: ¿qué es y porqué debe interesar a los desarrolladores Java?

Por: Andreano Lanusse

Resumen: El lenguaje Java es muy maduro y la mayoría de los nuevos proyectos Java no parten de cero.

Traducción: Jamir Avila. (ITTools)

El término Arqueología de Software se ha utilizado en diversas formas desde comienzos de 2001. El concepto de Arqueología de Software es un enfoque o metodología que ayuda a los miembros de un equipo o al equipo completo a entender exactamente lo que tienen en el código con el que van a estar trabajando. El enfoque también es muy útil cuando se descompone una pieza de software existente para encontrar patrones de diseño y desarrollo que podrían ser “cosechados” en desarrollos futuros.

La gran cosa sobre la Arqueología de Software es que no pertenece a Java únicamente sino que se puede utilizar con cualquier lenguaje de software. Este artículo se centrará específicamente en Java pero el enfoque puede ser aplicado a casi cualquier tipo de proyecto de desarrollo. En el mercado actual, en el que el lenguaje Java es muy maduro y la mayoría de los nuevos proyectos no parten de cero, sino que se enfocan más en extensión y mantenimiento, donde la meta final es hacer que el software existente corra mejor.

El proceso de Arqueología de Software puede realmente ahorrar una cantidad significativa de trabajo, o en muchos casos, el volverlo a hacer. Entonces, ¿qué retos enfrentan todos los desarrolladores cuando se les pide hacer este tipo de proyectos?

  • ¿Qué se ha heredado?
  • ¿Qué piezas deben ser conservadas?
  • ¿Dónde están las secciones tenebrosas del código?
  • ¿Qué tipo de equipo de desarrollo lo creó?
  • ¿Dónde están los puntos de rendimiento por los que me debería preocupa?
  • ¿Qué hace falta que me causará problemas significativos más adelante en el proceso de desarrollo?

El enfoque general se divide en un proceso de seis pasos. Al momento en que un equipo ha terminado, y ha revisado que hay y que no, el proceso puede ayudar drásticamente a definir la estrategia de desarrollo del proyecto que debe seguirse. Los seis pasos incluyen:

  • Visualización: representación visual del diseño de la aplicación.
  • Violaciones de diseño: conocimiento de la salud del modelo de objetos.
  • Violaciones de estilo: comprensión del estado actual del código.
  • Revisión de la lógica de negocio: habilidad para probar las fuentes existentes.
  • Revisión de rendimiento: ¿dónde están los cuellos de botella en el código fuente?
  • Documentación: ¿el código tiene la documentación adecuada para que la gente entienda en que están trabajando?

La mayoría de los desarrolladores se referirán a estos pasos como OPM (Otro Proceso Más), en inglés /Yet Another Process/, pero en realidad muchos de ellos deberían ser parte del proceso diario del desarrollador, por lo que no debe ser demasiado abrumador. La siguiente pregunta es ¿pueden estas tareas ser hechas a mano?. Desde un punto de vista puramente técnico, la respuesta tendría que ser si, pero en el mundo de hoy de plazos más cortos y elevadas expectativas del usuario, el tiempo necesario para hacer esto manualmente es inaceptable.

Luego si realmente no pueden ser hechas a mano, ¿qué herramientas se necesitan para hacer el trabajo?. Vamos a descomponer el proceso paso por paso y a mirar las herramientas que se podrían utilizar para completar la tarea. Existen algunos entornos integrados de desarrollo avanzados que incluyen todas estas herramientas y están basados en herramientas de código abierto que pueden hacer algunas partes del trabajo.

La visualización es el primer paso para entender con qué tipo de código va a trabajar el va a trabajar. Siempre me asombra cuántos desarrolladores nunca han visto una visualización del código que han escrito. Muchas veces los elementos clave de la arquitectura puede ser descubiertos con sólo mirar un diagrama de objetos del sistema. Cosas como las relaciones entre los objetos y el nivel de la herencia pueden verdaderamente abrir los ojos. El viejo adagio es cierto: una imagen vale más que 1000 líneas de código. Cuando se piensa en visualización en un lenguaje orientado a objetos como Java, los diagramas UML parecen ser ampliamente utilizados y comprendidos. Hacer posible la ingeniería inversa al código y generar el diagrama de clases es la primera herramienta que se necesita. Más adelante en el proceso será importante hacer ingeniería inversa a los métodos para generar diagramas de secuencia o de comunicación para una mejor comprensión de clases y métodos extremadamente complejos.

Una vez la visualización del sistema se hace y revisa, el siguiente paso es revisar el sistema desde el punto de vista de las violaciones del diseño. Se puede hacer mediante el uso de métricas de código estático.

El uso de métricas da al desarrollador o equipo una forma de comprobar la salud del diseño de objetos. Conocimientos básicos del sistema como líneas de código (LOC) o la siempre importante complejidad ciclomática (CC) pueden dar mucha información a quien hace la revisión.

Muchos desarrolladores no tiene idea de lo grande o pequeña que es la aplicación en la que están trabajaron o dónde están ubicadas las partes más complejas de la aplicación. El uso de un número selecto de métricas, permite a los desarrolladores detectar áreas de “problemas”; estas áreas deben ser marcadas para futuras revisiones, ya que normalmente son las que deben ser modificadas. También se pueden hacer análisis adicionales, sobre los métodos que han sido marcados como demasiados complejos, mediante la generación de diagramas de secuencia. Estos diagramas ofrecen una representación gráfica condensada y hacen mucho más fácil a desarrolladores y administrador entender la tarea de actualizar o cambiar los métodos. Otra métrica valiosa es la prueba de cobertura de JUnit (JUC). En muchos casos cuando el código es heredado un número bajo o inexistente en torno a las pruebas JUnit se presenta y debería plantear mayores preocupaciones sobre la introducción de cambios al sistema. La mayor preocupación será como asegurar que los cambios hechos al código o las correcciones implementadas sean correctos y no rompan otras partes del sistema. El uso de la información de las herramientas que generan métricas permite a los desarrolladores tener una mejor comprensión de lo que se ha heredado y de algunas de las complicaciones del producto.

Las violaciones de estilo ayudan a completar la imagen del código heredado. Muchos desarrolladores sostienen que las auditorías de código estático deben ser ejecutadas en primer lugar, y esto es cierto desde la perspectiva de un nuevo proyecto. Sin embargo, cuando se heredan cantidades masivas de código, ejecutar las métricas primero usualmente da más información basada en la salud de los objetos. Una vez la salud del diseño de objetos es determinada y se puede señalar distintas áreas del código que necesitan trabajo significativo, las auditorías además pueden refinar ese conocimiento.

Las auditorías de código estático incluyen todo tipo de reglas que buscan en el código consistencia, cumplimiento de estándares, y malas prácticas. Herramientas de auditoría como las nuestras incluyen más de 200 auditorías y ayudarán en la comprensión de la complejidad de la aplicación bajo revisión. Herramientas de auditoría avanzadas incluyen reglas para encontrar cosas como clases dios, métodos dios, envidias, y cirugías por disparos de escopeta. Estas auditorías avanzadas realmente usan algunas de las métricas para dar a los revisores más información.

Tome los métodos dios como ejemplo. Se trata de métodos en una clase que son llamados desde todas partes, lo que significa en diseño orientado por objetos que el método tiene demasiada responsabilidad, luego al hacer cambios sobre uno de tales métodos podría tener un efecto dramático en todo el sistema. Miremos la envidia. Esto es casi exactamente lo opuesto de una clase dios; es una clase no hace mucho y que podría se reconstruida en la clase que la invoca. Cuando se estima la cantidad de tiempo que se le debe dar a una ampliación particular o se determina que tipo de código ha sido heredado este tipo de comprensión de bajo nivel vale mucho.

La revisión de la lógica de negocio se enfoca en la comprobación de una aplicación. Al usar métricas avanzadas el valor de las pruebas disponibles puede ser determinado en pocos minutos. Heredar una gran cantidad de código y encontrar que no existen pruebas unitarias va a tener un efecto dramático en las estimaciones de mejoras, o hacer que los desarrolladores se den cuenta de que probablemente no tienen forma de verificar que los cambios en el sistema sean correctos. Las herramientas necesarias para probar la lógica de la aplicación deben incluir un producto que haga la cobertura del código y un producto de pruebas unitarias integradas como JUnit. Tener uno de los dos está bien, pero contar con ambos abre la puerta a muchas nuevas posibilidades de pruebas. En primer lugar, al ejecutar las pruebas de unidad con una herramienta de cobertura de código, el código que va a ser probado se puede verificar. La cobertura del código también puede ser usada cuando no se tienen las herramientas de auditoría avanzadas discutidas anteriormente, además una buena herramienta de cobertura de código mostrará todas las clases y métodos incluidos en la ejecución de la prueba. El uso de una auditoría avanzada como la cirugía por disparo de escopeta resaltará métodos que tienen muchas dependencias, el uso combinado de pruebas de unidad y de cobertura de código asegura que los cambios a este tipo de métodos pueda ser completamente probado y verificado. Otra de las ventajas de la cobertura de código se encuentra en el control de calidad (QA), que ejecuta las secuencias de prueba del producto mientras la cobertura de código esté activa. Dirá dos cosas: cuando la secuencia de pruebas está completa y si hay cobertura de todo el código de la aplicación. Lo bueno de esta pieza de la Arqueología de Software es que por lo general solamente puede mejorar. Al añadir pruebas adicionales, el resultado final debería ser un mejor sistema en funcionamiento.

La necesidad de un buen perfilador es clave para la revisión de rendimiento. El uso de las herramientas y resultados de la revisión de la lógica de negocio, permite descubrir y reparar problemas de rendimiento. Una métrica clave de recordar es que solamente alrededor del 5% del código causa la mayoría de los problemas de rendimiento. Así que contar con un manejador donde el código se vuelve complejo hace el mantenimiento más fácil y rápido.

El último paso es la documentación. Hacer todo este trabajo es enorme para el desarrollador, el revisor, o el equipo que intenta entender el sistema. Sería grandioso si el trabajo pudiera ser capturado y usado en el futuro. Tener un generador automático de documentación ahorra tiempo, reduce la sobrecarga, y ayuda a asegurar que la documentación esté actualizada. Hará más fácil a nuevos miembros unirse al equipo o que la aplicación sea pasada a otro equipo.

Las ideas en torno de la Arqueología de Software son bastante sencillas; este artículo tomó un enfoque de heredar una gran cantidad de código y entonces responsabilizarse por ese código. Otras expediciones en el código podrían producir útiles patrones de diseño, grandes algoritmos para reutilización, o evitar grandes cosas. Todos sabemos que el software es un activo luego usando la Arqueología de Software se puede asegurar sacar el mayor provecho de esa inversión.



Respuesta del Servidor desde: ETNASC04