• No results found

Caso de estudio #2: Visualización 

 

 

 

 

Aplicación: Health Watcher

 

   

Este estudio evalúa si las mejoras de visualización de resultados implementadas        sobre la herramienta JSpIRIT en este trabajo aportan información relevante que        ayude a detectar problemas en la arquitectura de los sistemas y/o problemas no        detectados utilizando la lista de resultados que provee la versión original de la        herramienta. Este contexto es particularmente aplicable en casos en que los        análisis arrojan una gran cantidad de smells y aglomeraciones, y el desarrollador        necesita tener una perspectiva del estado general del sistema. El análisis de los        code smells y las aglomeraciones permite a los desarrolladores entender los        problemas potenciales para decidir si deben o no ser refactorizados. Este        experimento se llevó a cabo en Health Watcher, una aplicación web cuyo        objetivo es permitir a los ciudadanos registrar quejas acerca de problemas de        salud en instituciones públicas. La aplicación contiene 135 clases y JSpIRIT        arrojó un total de 58 smells y 82 aglomeraciones en el análisis. 

   

7.1 JSpIRIT ­ Análisis de code smells 

 

A continuación se realiza un análisis de los smells detectados por JSpIRIT        tomando el rol de un desarrollador en la interpretación de los resultados        obtenidos. 

   

7.1.1 Vista de Heat Map

   

Si bien el muestreo de resultados tradicional extrae los smells que se consideran        relevantes, no ofrece una perspectiva general del sistema. Cuando el        desarrollador navega los elementos de código afectados, su visión puede verse       

reducida a solucionar los problemas que encuentra en cada clase y continuar con        el siguiente smell. Existen ocasiones en las cuales un problema puede superar el        scope de una clase, es decir, expandirse a una jerarquía de clases e incluso        pudiendo afectar a otros componentes que hacen uso de las mismas. Si bien el        smell es un indicador de que puede existir un problema en una clase esto no        significa que termine ahí. Es posible que el smell se contagie a todo un        componente o a otros sectores del sistema implicando malas decisiones en el        diseño del mismo. Por esta razón, es de utilidad tener una visión general del        sistema que provea otra perspectiva, en otras palabras que además de poder        analizar las partes sea posible analizar el todo. La Figura 7.1a muestra una vista        de “puntos calientes” del sistema desarrollada en este trabajo e introducida en el        Capítulo 5 con este objetivo. Según la visualización (Figura 7.1a) el paquete        más afectado del sistema es         healthwatcher.view.command. El paquete tiene un        total de 35 clases y presenta un total de 15 smells. El gran número de clases que        contiene el paquete no es un buen indicador [76], ya que puede significar que el        componente posee muchas responsabilidades. La visualización de Heat Map        además agrupa y provee un detalle de las clases afectadas en el paquete en        cuestión y los smells afectantes (Figura 7.1b). Explorando la lista de smells de        este paquete provista por la visualización (Tabla 7.2) se puede ver que 2 de        estos corresponden a los smells #3 y #5 rankeados por JSpIRIT en su vista de        smells tradicional. Incluyendo a estos dos, 12 de los 15 smells encontrados en el        paquete comparten una particularidad, todos afectan a métodos bajo el mismo        nombre, execute(). Como esto raramente podría ser una casualidad es necesario        analizar las responsabilidades asociadas a estos métodos y su relación en caso        de que existiera. Muchos de los smells encontrados son del tipo       Dispersed  Coupling  sobre el método      execute()  lo que sugiere que el método utiliza        operaciones definidas en varias clases del sistema. 

 

Figura 7.1a: Health Watcher ­ Vista de Heat Map 

Navegando sobre las clases detalladas por la visualización para el paquete       

healthwatcher.view.command  (Tabla 7.1) se observa que la gran mayoría        extiende a una clase abstracta         Command que se encuentra en el mismo paquete        y define un método abstracto      execute()  para ser implementado por sus          subclases, en total 32. Estas clases intentan seguir el patrón de diseño        “Command”, el hecho es que el comportamiento de los métodos debería diferir        de una clase a otra, sin embargo muchas de ellas presentan un comportamiento        similar, incluso muchas de ellas comparten en su nombre el mismo prefijo,        haciendo alusión a que tal vez ejecutan operaciones similares sobre entidades        diferentes. En efecto, cada una de estas 32 clases realiza una operación de        inserción, actualización o búsqueda sobre una base de datos en base a una        petición recibida. Probablemente sería posible reducir notablemente la cantidad        de subclases realizando una abstracción del comportamiento basado en el tipo        de operación que realiza cada una.         Code Smell  Ranking  Dispersed [email protected]  24  Dispersed [email protected]  27  Brain [email protected]  Intensive [email protected]  14  Dispersed [email protected]  35  Brain [email protected]  Dispersed [email protected]  40  Dispersed [email protected]  41  Dispersed [email protected]  43  Dispersed [email protected]  48  Shotgun [email protected]  21  Shotgun [email protected]  22  Shotgun [email protected]  23 

Dispersed [email protected]  53  Dispersed [email protected]  54    Tabla 7.1: Code smells afectando al paquete healthwatcher.view.command.     

Otro indicador que refuerza las sospechas de la existencia de un problema        en el paquete son los smells encontrados del tipo       Shotgun Surgery     (Tabla 7.1).     Como se dijo anteriormente cada una de las 32 clases que extienden a la clase       

Command actúan en base a peticiones, estas son implementadas por la clase       

CommandRequest,  y sus instancias son utilizadas por las subclases de       

Command, lo que significa que cualquier modificación en las signaturas de los        métodos de    CommandRequest  impactaría en todas y cada una de estas        subclases. En efecto, los smells del tipo       Shotgun Surgery    sobre un elemento de        código (contrariamente al tipo        Dispersed Coupling  ) indican que cualquier        modificación sobre este tendrá un gran costo asociado, debido a los cambios        necesarios en una gran cantidad de clases que lo utilizan. 

 

Luego de haber explorado un poco los elementos de código del sistema y        de haber adquirido un mejor entendimiento del mismo se pudo establecer una        aproximación a la arquitectura pretendida por sus desarrolladores. Incluso los        prefijos de los nombres de los paquetes sugieren que el sistema contiene tres        componentes principales que modelarían una arquitectura Cliente/Servidor por        capas [77]:     1. Capa de presentación (healthwatcher.view.*)    2. Capa de negocio: (healthwatcher.business.*)   

3. Capa de datos: (healthwatcher.data.* y healthwatcher.model.*)   

En esta arquitectura (Figura 7.2) la capa de negocio actúa de intermediario entre        las capas de presentación y de datos, esto produce una mejora en la        modificabilidad del sistema, aislando la funcionalidad de cada capa y        reduciendo el impacto ante un eventual cambio en una de ellas. 

 

 

Figura 7.2: Arquitectura Cliente/Servidor de tres capas. 

    

Para lograr este aislamiento entre las capas, cada una de ellas solo debe poder        comunicarse con sus capas aledañas. Gracias a la visualización de las        dependencias de los paquetes afectados provista por la vista de heat map (Figura        7.4) se pudo detectar que esto no se respetaba en el sistema Health Watcher. La        Figura 7.3 muestra un diagrama de los módulos de Health Watcher, en líneas        negras se representan las dependencias que deberían tener los módulos, mientras        que en líneas punteadas de color rojo se representan las dependencias entre        módulos que violan a la arquitectura pretendida.    Figura 7.3: Vista de módulos de Health Watcher.         

Como se observa en la Figura 7.4, el paquete       healthwatcher.view.command que  formaría parte del módulo GUI (Figura 7.3), tiene varias dependencias directas        con paquetes de prefijo       healthwatcher.model, que pertenecerían a la capa de        datos, violando el diseño definido por la arquitectura.         Figura 7.4: Violación en la arquitectura de Health Watcher.     

Si el código se correspondiera con la arquitectura, todas las relaciones entre los        paquetes healthwatcher.view.* y los paquetes     healthwatcher.model.* deberían  ser transitivas a través de cierta lógica implementada en los paquetes       

de dependencia que parten desde paquetes       healthwatcher.view.* hacia paquetes   

healthwatcher.business.*  por un lado, y por otro lado dependencias desde        paquetes healthwatcher.business.* hacia paquetes healthwatcher.model.*

El problema anterior está asociado con el manejo de excepciones. Por        ejemplo, la clase      SearchData  invoca a diferentes servicios        del módulo    BUSINESS. SearchData luego termina manejando excepciones arrojadas por el        módulo DATA, incluyendo aquellas que deberían ser tratadas internamente.        Esto conlleva a un acoplamiento adicional entre los elementos que implementan        los módulos DATA y GUI, resultando en una violación de la arquitectura. 

En la vista de heat map también se puede visualizar otra violación de la        arquitectura marcada en la Figura 7.3 que muestra una dependencia desde el        módulo BUSINESS (correspondiente a la lógica del negocio) hacia el módulo        GUI (Interfaz Gráfica de Usuario).  

Figura 7.5: Violación en la arquitectura de Health Watcher. 

   

Esta dependencia indeseada se puede visualizar en el heat map de la        Figura 7.5 observando las dependencias del paquete       healthwatcher.business.  Allí se puede ver como el paquete      healthwatcher.business  del módulo    BUSINESS utiliza al paquete healthwatcher.view perteneciente al módulo GUI.   

 

Related documents