refactorizaciÓn automatizada para la eliminaciÓn de

74
TESIS DE GRADO EN INGENIERÍA DE SISTEMAS REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE FEATURE ENVY por Antivero, Juan Pablo Arias, Lucas Director: Vidal, Santiago A. Co-Directora: Marcos, Claudia A. FACULTAD DE CIENCIAS EXACTAS UNIVERSIDAD NACIONAL DEL CENTRO DE LA PROVINCIA DE BUENOS AIRES Tandil, Argentina 2018

Upload: others

Post on 20-Jul-2022

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

TESIS DE GRADO EN INGENIERÍA DE SISTEMAS

REFACTORIZACIÓN AUTOMATIZADA PARA LA

ELIMINACIÓN DE FEATURE ENVY

por

Antivero, Juan Pablo

Arias, Lucas

Director: Vidal, Santiago A.

Co-Directora: Marcos, Claudia A.

FACULTAD DE CIENCIAS EXACTAS

UNIVERSIDAD NACIONAL DEL CENTRO DE LA PROVINCIA DE

BUENOS AIRES

Tandil, Argentina

2018

Page 2: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

2

Índice

Capítulo 1: Introducción ................................................................................. 8

1.1 Calidad de software .................................................................................................. 8

1.2 La problemática de los Code Smell .......................................................................... 9

1.3 Extensión de Bandago .............................................................................................. 10

1.4 Esquema general ...................................................................................................... 12

Capítulo 2: Calidad y mantenimiento de software ..................................... 13

2.1 Calidad de software .................................................................................................. 13

2.2 Refactoring ............................................................................................................... 14

2.3 Code Smells ............................................................................................................... 15

2.3.1 Feature Envy .......................................................................................................... 17

2.3.2 Refactoring de Feature Envy ................................................................................. 18

2.3.2.1 Program Slicing ............................................................................................. 18

2.3.2.2 Statements ..................................................................................................... 18

2.3.2.3 Problemática del Move Method .................................................................... 19

Capítulo 3: Herramientas de refactorización y análisis de

Feature Envy ............................................................................. 20

3.1 Enfoques del refactoring de Feature Envy ............................................................ 20

3.2 Herramientas ............................................................................................................ 20

3.2.1 Herramientas de recomendación de refactoring ..................................................... 20

3.2.1.1 MethodBook .................................................................................................. 21

3.2.1.2 MORE ........................................................................................................... 22

3.2.1.3 c-JRefRec ...................................................................................................... 25

3.2.1.4 JMove ........................................................................................................... 27

3.2.2 Herramientas de aplicación de refactorings ........................................................... 28

3.2.2.1 Eclipse ........................................................................................................... 29

3.2.3 Herramientas de recomendación y aplicación de refactorings ................................ 29

3.2.3.1 JDeodorant .................................................................................................... 29

3.3 Criterios de comparación ........................................................................................ 30

3.3.1 Comparación y conclusiones ................................................................................. 31

Page 3: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

3

Capítulo 4: Un enfoque iterativo para la refactorización de

Feature Envy ............................................................................ 33

4.1 Refactorización de Feature Envy .......................................................................... 33

4.2 Esquema general de la solución iterativa de Feature Envy ................................ 34

4.3 Desarrollo del enfoque iterativo para la refactorización de Feature Envy ........ 36

4.3.1 Actividad 1: Obtener características del método .................................................... 36

4.3.2 Actividad 2: Elegir la clase candidata .................................................................... 38

4.3.3 Actividad 3: Seleccionar el fragmento de código a mover ..................................... 39

4.3.4 Actividad 4: Calcular las métricas de la solución generada ................................... 41

4.3.5 Actividad 5: Aplicar el refactoring ........................................................................ 42

4.3.6 Actividad 6: Corregir errores ................................................................................. 43

4.4 Implementación de la solución ................................................................................ 44

4.4.1 Aplicación de refactorings .................................................................................... 44

4.4.2 Vista arquitectónica de Bandago ........................................................................... 45

Capítulo 5: Casos de estudio ........................................................................ 49

5.1 Proyectos evaluados y operatoria de la evaluación ............................................... 49

5.2 Características de las Feature Envy ....................................................................... 51

5.3 RQ #1: ¿Qué porcentaje de Feature Envy son automáticamente eliminadas por

la tool, sin necesidad de correcciones por parte del desarrollador? ........................... 54

5.3.1 Hipótesis ............................................................................................................... 54

5.3.2 Análisis e Interpretación ....................................................................................... 54

5.4 RQ #1: ¿Qué porcentaje de Feature Envy son automáticamente eliminadas por

la tool, sin necesidad de correcciones por parte del desarrollador? ........................... 59

5.4.1 Hipótesis ............................................................................................................... 59

5.4.2Análisis e Interpretación ........................................................................................ 60

5.5 RQ #1: ¿Qué porcentaje de Feature Envy son automáticamente eliminadas por

la tool, sin necesidad de correcciones por parte del desarrollador? ........................... 64

5.5.1 Hipótesis ............................................................................................................... 64

5.5.2 Análisis e Interpretación ....................................................................................... 65

Capítulo 6: Conclusión .................................................................................. 69

6.1 Conclusiones finales ................................................................................................. 69

6.2 Contribuciones .......................................................................................................... 70

Page 4: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

4

6.3 Limitaciones .............................................................................................................. 70

6.4 Trabajos futuros ....................................................................................................... 71

Bibliografía .................................................................................................... 72

Page 5: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

5

Índice de Figuras

1.1 Esquema base de la herramienta ..................................................................................... 11

2.1 Etapas del proceso de refactoring .................................................................................. 14

2.2 Detección de Feature Envy ............................................................................................ 17

3.1 Proceso utilizado por MethodBook para encontrar recomendaciones ........................... 21

3.2 Arquitectura del recomendador de refactorings MORE ................................................ 23

3.3 Vista Class State View de la herramienta c-JRefRec .................................................... 26

3.4 Vista Refactoring Candidates View de la herramienta c-JRecRef ................................ 26

3.5 Interfaz de JMove .......................................................................................................... 28

3.6 Presentación de Feature Envy de JDeodorant ................................................................ 30

4.1 Correlación entre code smells. Lanza y Marinescu ....................................................... 33

4.2 Esquema general de la solución de Feature Envy ......................................................... 35

4.3 JSpIRIT Smells View .................................................................................................... 37

4.4 Llamados a variables de instancia de la propia clase del método ejemplo..................... 37

4.5 Identificación de llamados a clases externas ................................................................. 39

4.6 Selección de statement o conjunto de statements a extraer ........................................... 40

4.7 Selección del statement candidato a ser extraído para la clase

name.gyger.jmoney.model.Entry.......................................................................................... 41

4.8 Cálculo de las métricas de la solución generada (Bandago View) ................................. 42

4.9 Selección de una solución para Feature Envy (Bandago Wizard).................................. 43

4.10 Método movido a la clase candidata............................................................................. 43

4.11 Extracción de un método previo a ser movido ............................................................. 45

4.12 Diagrama de contexto de Bandago .............................................................................. 46

4.13 Arquitectura de alto nivel de Bandago ......................................................................... 48

5.1 Diagrama de la operatoria del experimento .................................................................... 51

5.2 Boxplot para la métrica ATFD ...................................................................................... 52

5.3 Boxplot para la métrica LAA ........................................................................................ 53

Page 6: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

6

5.4 Boxplot para la métrica FDP ......................................................................................... 53

5.5 Extracción Total vs Extracción Parcial .......................................................................... 58

5.6 Cantidad de soluciones identificadas .............................................................................. 58

5.7 Limitaciones de Eclipse al aplicar el refactoring Move Method .................................... 59

5.8 Cantidad de smells solucionados por el enfoque ........................................................... 61

5.9 Porcentajes de smells solucionados ............................................................................... 62

5.10 Cantidad de smells creados por el enfoque .................................................................. 62

5.11 Porcentajes de smells creados....................................................................................... 63

5.12 Code Smells afectados por el enfoque .......................................................................... 64

5.13 Cantidad de Feature Envy identificadas por JDeodorant y JSpIRIT ............................ 65

5.14 Porcentaje de resolución de ambas herramientas sobre la intersección ...................... 66

5.15 Método solucionado por JDeodorant y no solucionado por el enfoque propuesto ...... 66

5.16 Cantidad de Feature Envy resueltas por ambas herramientas ...................................... 67

5.17 Porcentaje de Feature Envy resueltas por ambas herramientas ................................... 68

Page 7: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

7

Índice de Tablas

2.1 Code Smells catalogados por Lanza y Marinescu .......................................................... 16

2.2 Métricas utilizadas por la herramienta............................................................................ 17

3.1 Selección de refactorings basado en reglas de MORE ................................................... 25

3.2 Categorías de las herramientas ...................................................................................... 31

3.3 Características de las herramientas ................................................................................. 31

4.1 Priorización de clases externas accedidas por la Feature Envy ...................................... 39

4.2 Elementos de la arquitectura de Bandago....................................................................... 46

5.1 Proyectos evaluados ....................................................................................................... 49

5.2 Cantidad de Feature Envy por proyecto ........................................................................ 51

5.3 Resultados de Feature Envy analizadas y resueltas automáticamente ........................... 55

5.4 Resultados de Feature Envy analizadas y resueltas luego de la intervención por parte del

desarrollador ........................................................................................................................ 56

5.5 Resultados de Feature Envy analizadas y resueltas ........................................................ 57

5.6 Comparación de Code Smells pre y post refactoring .................................................... 60

Page 8: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

8

Capítulo 1: Introducción

1.1 Calidad de software

En los sistemas de software es muy importante centrar el desarrollo en su calidad [22,23]. En

el contexto del software, calidad es "la totalidad de aspectos y características de un producto

o servicio que tienen que ver con su habilidad de satisfacer las necesidades explícitas o

implícitas" [12]. Para asegurar esto es que existe el ciclo de vida del software, metodologías

de desarrollo, modelos de mejora continua de procesos y distintos aspectos relacionados al

área de SQA (Sofware Quality Assurance, es decir, Garantía de la Calidad de Software) [24].

Sin embargo, la calidad y la estructura de los sistemas se ven deterioradas a menudo,

generalmente como resultado de los cambios que introducen los programadores para resolver

objetivos a corto plazo, sin conocer completamente el diseño del código [2]. Estos problemas

de diseño normalmente son conocidos como code smells. Un code smell (también llamado

bad smell), se refiere a cualquier síntoma que puede indicar que el código fuente presenta

problemas [2], como lo es el código duplicado, métodos o clases muy largos, mal

encapsulamiento de clases o extensas listas de parámetros, entre otros.

Feature Envy es un code smell que impacta principalmente en la modificabilidad del sistema.

Lanza y Marinescu [3] lo definen de la siguiente manera:

“La desharmonía de diseño Feature Envy se refiere a los métodos que parecen más

interesados en los datos de otras clases que en los de su propia clase. Estos métodos acceden

o una gran cantidad de datos de otras clases directamente o mediante métodos de acceso”

La presencia de Feature Envy afecta negativamente el mantenimiento y la extensibilidad,

minimizando la cohesión de una clase y generando el riesgo de sufrir un efecto en cascada

(un cambio en un método dispara cambios en otro método y así sucesivamente).

Es importante señalar que la calidad del software no se refiere únicamente a obtener un

producto sin errores, sino también a que su código fuente se pueda extender, modificar de

manera simple y entender sin que esto resulte un problema con el paso del tiempo, debido a

que la etapa posterior a la entrega es la parte más importante en el desarrollo de software

[14]. La existencia y aumento de code smells generan una degradación de la calidad del

software, impactando fuertemente sobre la comprensión, mantenimiento y evolución del

código fuente [1].

La manera de solucionar los code smells es mediante la refactorización [2] del código fuente.

Refactorizar, en Ingeniería de Software, se describe como el proceso de realizar un cambio

en la estructura interna del software para que este sea más fácil de entender y más simple de

modificar sin cambiar su comportamiento. El refactoring es realizado por los desarrolladores

como parte del proceso de desarrollo del software, ya que incrementa la legibilidad y

mantenibilidad. Este proceso, además, permite mejorar el diseño del software mejorando su

Page 9: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

9

modularización y evitando así, en muchos casos, una mayor cantidad de código para realizar

una misma tarea debido a código duplicado.

1.2 La problemática de los Code Smell

A pesar de la importancia del proceso de refactoring como medio para mantener la calidad

del software, éste no siempre es realizado con la frecuencia ni con el tiempo que requiere. La

falta de refactorings, en general, se debe a lo complejo y costoso que puede resultar el proceso

de detección de code smells, la forma de solucionarlos, y el riesgo de generar errores durante

el proceso. También, en la industria, la frecuencia y tiempo que se le dedica a este proceso

se ve afectada por los cortos tiempos de entrega que se disponen.

El autor K. Beck, en uno de sus libros sobre la metodología ágil eXtreme Programming,

afirma que el refactoring ahorra tiempo en desarrollo y mejora la calidad [18], instando a los

desarrolladores a incluir al refactoring como una etapa que sea parte del ciclo de desarrollo

del software. Por otro lado, existe la idea de que los ingenieros de software a menudo evitan

el refactoring cuando se encuentran limitados con respecto a recursos y tiempos de entrega

[16]. En general, muy pocos desarrolladores se acercan a un equilibrio entre la adición de

nueva funcionalidad y la utilización de refactoring. En cualquiera de los casos, la falta de

herramientas que determinan el impacto real del refactoring y sus efectos secundarios,

contribuyen con la decisión de posponer el refactoring reiteradas veces, y en la mayoría de

los casos nunca es ejecutado [17].

Un estudio de campo realizado por Kim, Zimmermann y Naggapan [19] muestra algunas

contradicciones en sus resultados acerca de los beneficios de aplicar refactorizaciones.

Aunque muchos programadores afirman que el uso de refactoring disminuye la cantidad de

bugs, otros señalan que en muchas ocasiones aparecen bugs de regresión al refactorizar. Sin

embargo, la causa de este inconveniente ha sido analizada por Murphy-Hill et al. [21], que

encontró que desarrolladores usualmente ejecutan refactorings junto con otros cambios que

alteran el comportamiento, además que los refactorings son aplicados en forma manual en

lugar de utilizar una herramienta que automatiza el proceso. Este tipo de prácticas son

propensas a introducir errores en el código.

La Feature Envy es un code smell sobre el cual se posee poca información que permita inferir

un método automatizado intuitivo para eliminarla. Martin Fowler [2] plantea que la solución

consiste en mover el método a la clase de la cual envidia el mismo mediante el refactoring

Move Method. En caso de que únicamente una parte del método sufra esta anomalía,

previamente hay que extraerla mediante Extract Method para luego realizar el Move

únicamente de esa parte.

Realizar manualmente este proceso puede ocasionar problemas de compilación y/o de

modificabilidad. Se deben comprobar las dependencias para no correr el riesgo de afectar el

funcionamiento del código, ya sea generando errores o incluso cambiando el comportamiento

original del programa accidentalmente.

Adicionalmente se deben tener en cuenta cuatro condiciones al realizar el refactoring Extract

Method:

Page 10: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

10

El código seleccionado para extraerse tiene que ser una lista de sentencias.

Dentro del fragmento de código no pueden existir asignaciones a variables que sean

utilizadas luego en el flujo del método. En el caso de Java, se puede permitir la

asignación de una variable y ésta será la variable de retorno en el método.

No pueden existir sentencias del tipo return.

El bloque de código no puede contener ramas de ejecución que vayan por fuera del

código seleccionado.

En cuanto al uso de Move Method, adicionalmente se deben tener en cuenta las condiciones

que imposibilitan la realización del mismo:

El método no debe estar declarado en superclases o subclases.

Deben modificarse todos los llamados que referencien a ese método.

En la clase candidata a la cual se moverá no debe existir un método del mismo

nombre.

El método no debe sobreescribir un método abstracto.

El método debe referenciar a la clase candidata a través de sus parámetros o de los

campos de la clase original.

Debido a la complejidad que conlleva el control de todos los puntos para asegurar que no se

ha modificado la funcionalidad del sistema ni se han introducido errores de compilación, es

importante encontrar la forma de automatizar la refactorización de Feature Envy.

Pocos estudios intentan solucionar code smells con una refactorización automatizada [25]

[40] [41]. En el caso de Feature Envy, existen herramientas que intentan lograrlo. Sin

embargo, ninguna solución conocida intenta la extracción (Extract Method) previa al Move

Method.

Existen herramientas, como JDeodorant [25] que han logrado una correcta solución a este

code smell, siempre y cuando se pueda mover el método completo a la clase candidata. Se

requiere realizar un análisis más detallado para lograr la identificación de métodos en los que

únicamente es necesario mover una parte del mismo.

1.3 Extensión de Bandago

En este trabajo se presenta una extensión de la herramienta Bandago [20] para el code smell

Feature Envy. Bandago es una herramienta que tiene como objetivo la solución de code

smells y luego el análisis del costo beneficio de la solución mediante la presentación de

métricas pertinentes. Originalmente dicha herramienta poseía la funcionalidad para

solucionar el code smell Brain Method, y fue extendida para soportar la resolución de Feature

Envy.

Para solucionar el code smell Feature Envy se aplican los refactorings Move Method y

Extract Method [2]. De esta forma se mueve el método a la clase en la cual se debería

encontrar. En caso de no poder realizarse esta acción directamente, se buscan alternativas

Page 11: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

11

para extraer la parte del método que genere Feature Envy y moverla a la clase candidata. Así

se logra poner en un mismo lugar el método y los datos que se utilizan conjuntamente [2],

minimizando la posibilidad de "efectos cascada" (un cambio en un método dispara cambios

en otro método sucesivamente) y se maximiza la cohesión [3].

Figura 1.1: Esquema base de la herramienta.

La Figura 1.1 muestra un esquema del enfoque propuesto donde se observa la Feature Envy

como la entrada, el código refactorizado como la salida y componentes que fueron utilizados,

encargados de realizar el análisis del código afectado y de aplicar el refactoring. Se realizó

un enfoque heurístico sobre la herramienta Bandago [20] y se utilizó como entrada la

herramienta JSpIRIT [13] para la detección de los code smells. El análisis de las métricas

tiene como base las investigaciones de Lanza y Marinescu [3]. También, se estudiaron las

herramientas que provee el IDE Eclipse para la extracción de código, y especialmente para

la realización de Move Method, debido a que actualmente la API de Eclipse no provee un

soporte completo para realizar correctamente este refactoring programáticamente.

Para poder validar los beneficios del enfoque se realizó un caso de estudio donde se

respondieron 3 research questions. Estas fueron:

RQ#1: ¿Qué porcentaje de Feature Envy son automáticamente solucionadas por el

enfoque propuesto, sin necesidad de intervención del desarrollador?

RQ#2: ¿Solucionar las Feature Envy permite solucionar otros Code Smells?

RQ#3: ¿Son complementarias las soluciones identificadas por el enfoque propuesto

y por JDeodorant en la refactorización de Feature Envy?

Estas Research Questions corroboraron la efectividad del enfoque, permitiendo identificar

un alto porcentaje de soluciones sobre el total de Feature Envy de un sistema. En la RQ#1,

se analizaron todas las Feature Envy que se lograron solucionar automáticamente sin

intervención por parte del desarrollador. Para la RQ#2, se analizó si la solución de Feature

Envy permite solucionar otros code smells detectados por JSpIRIT. Para la RQ#3, se

comparó el enfoque propuesto con otra herramienta de recomendación y aplicación de

refactors para la eliminación de Feature Envy, llamada JDeodorant [25].

Page 12: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

12

La refactorización de este code smell lleva a una mejora en la cohesión y el acoplamiento del

software. Se obtuvo como resultado un código fuente mejor estructurado, más legible y con

mejor diseño.

Las contribuciones del trabajo final son las siguientes: Se logró automatizar todo el proceso

de refactorización de las Feature Envy, generando una solución válida. Se pueden visualizar

el conjunto de métricas relacionadas que justifican la aplicación de la solución propuesta.

Además, se extendió la funcionalidad de Bandago para hacerlo más configurable a las

necesidades de un desarrollador. Otro aporte importante es el análisis automatizado de

posibilidades de extracción en caso de no poder mover el método completo, ya que no existe

precedencia en la aplicación de este análisis adicional al intentar resolver una Feature Envy.

1.4 Esquema general

El esquema general de la tesis está organizado de la siguiente manera:

En el capítulo 2 se presentan los conceptos de la calidad y mantenimiento de software. Así

mismo, se introducirán temas clave como la noción de code smell y refactorización.

En el capítulo 3 se describen herramientas enfocadas a refactorizar automáticamente una

Feature Envy. Adicionalmente, serán comparados entre sí.

En el capítulo 4 se presenta el enfoque de la solución planteada. Se desarrollarán las

actividades y se describirán detalladamente. Luego, se presentarán la implementación y el

diseño de la solución.

En el capítulo 5 se presenta un caso de estudio que responde las research questions. Se

presenta la operatoria que se utilizó en el caso de estudio y posteriormente el análisis de los

resultados obtenidos.

Finalmente, el caso 6 resume conclusiones, contribuciones principales, limitaciones y el

trabajo futuro.

Page 13: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

13

Capítulo 2: Calidad y mantenimiento de software

2.1 Calidad de software

En el contexto del software, calidad es "la totalidad de aspectos y características de un

producto o servicio que tienen que ver con su habilidad de satisfacer las necesidades

explícitas o implícitas" [12]. Para asegurar esto es que existe el ciclo de vida del software,

metodologías de desarrollo, modelos de mejora continua de procesos y todo lo relacionado

al área de SQA (Sofware Quality Assurance, es decir, Garantía de la Calidad de Software)

[24]. Por lo tanto, es muy importante centrar el desarrollo en su calidad [22,23].

La calidad de software hace referencia a dos puntos importantes: generar código libre de

errores y concentrarse en mantener la calidad del código con el paso del tiempo. Este último

punto es mucho más complejo para el software que para otros productos industriales [24].

Por lo tanto, la tarea de mantenimiento es dificultosa y requiere de un gran consumo de

tiempo si no se desea que se degrade la calidad de software.

Al realizar la tarea de mantenimiento de software, el conocimiento sobre el sistema es

importante. Entre el 40% y el 60% del esfuerzo realizado en mantener un sistema está

relacionado con el entendimiento del mismo [26]. Esto conlleva a que si es dificultoso

obtener la información necesaria sobre requerimientos que el sistema intenta satisfacer,

arquitectura utilizada, detalles técnicos, etc. el tiempo invertido en mantenimiento aumentará

considerablemente.

Así mismo, esta tarea no es un problema que debe ser resuelto o evitado. Es, en cambio, una

solución natural al hecho de que los sistemas de software deben mantenerse en sintonía con

el entorno y con las necesidades de los usuarios [26]. Lehman [29] marca como clave el

hecho de que los sistemas nunca están completos y siempre continúan evolucionando. A

medida que evolucionan, se vuelven más complejos a menos que se realicen acciones para

reducir su complejidad.

El mantenimiento de software está dado por 4 necesidades [28]:

1. Modificar el sistema para adaptarlo a nuevas necesidades (aproximadamente el 50%

de los proyectos de mantenimiento).

2. Adaptar el sistema a un entorno constantemente cambiante (aproximadamente el

25% de los proyectos de mantenimiento)

3. Corregir errores preventivamente (aproximadamente el 5% de los proyectos de

mantenimiento)

4. Corregir errores como resultado de un problema actual (aproximadamente el 20% de

los proyectos de mantenimiento)

Como puede apreciarse en los porcentajes, los mantenimientos más comunes son los

primeros dos. Esto ocurre porque la evolución del software está dada por dos grandes

razones. La primera razón es el cambio en los requerimientos, aspecto que se encuentra

fuertemente relacionado con el primer tipo de mantenimiento enumerado. La segunda razón

Page 14: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

14

es el cambio constante de la tecnología y el software, aspecto que se encuentra fuertemente

relacionado con el segundo mantenimiento enumerado.

Estos dos mantenimientos, que son los que recubren la mayor cantidad de proyectos, están

fuertemente ligados con el refactoring de un sistema. El refactoring lleva a un código más

mantenible y extensible. Este lleva a mantener el sistema evolucionable y adaptativo a los

cambios de requerimientos del sistema.

2.2 Refactoring

Refactorizar se describe como el proceso de realizar un cambio en la estructura interna del

software para que éste sea más fácil de entender y modificar sin cambiar su comportamiento.

Es decir, se modifica la estructura interna de un sistema de software, pero sin alterar el

comportamiento externo del mismo [29]. Es decir, con el mismo conjunto de entradas, el

programa genera la misma salida, antes y después de someterse al proceso de refactoring.

Aunque no cambie el comportamiento del programa, refactorizar puede ayudar al diseño y

evolución de un software, reestructurando el programa de una forma que permita introducir

cambios más fácilmente [30]. Los cambios extremadamente complicados en programas mal

estructurados pueden incluir tanto refactoring como cambios en el comportamiento.

El concepto de refactoring también tiene una estrecha relación con la programación orientada

a objetos, debido a que este paradigma hace más factible el uso de esta técnica al hacer más

explícita la información estructural necesaria para refactorizar un programa [30]. Algunas de

las actividades que se realizan con este objetivo son: reducir la duplicación de código,

mejorar la cohesión, reducir el acoplamiento, mejorar atributos de calidad como la

legibilidad, flexibilidad, mantenimiento, etc.

Para realizar un refactoring, se deben cumplir las siguientes 3 etapas [31]:

Figura 2.1: Etapas del proceso de refactoring

Page 15: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

15

Como se ve en la Figura 2.1, las etapas son:

1. Decisión para refactorizar: Esta etapa ocurre antes de realizar el refactoring

propiamente dicho. Consiste en las decisiones previas relacionadas con aspectos

personales (quienes lo van a realizar) y la situación actual del código (qué refactorings

se aplicarán para generar una solución valiosa).

2. Proceso de refactorización: Hace referencia a realizar las actividades de refactoring.

Se deben definir las herramientas que se utilizarán para las mismas.

3. Resultados de la refactorización: Se refiere al análisis posterior, que determinará si se

introdujo algún error y si realmente la solución generó algún valor agregado al código

existente.

Como se puede apreciar, el proceso de refactorización comienza al analizar la situación actual

del código para identificar oportunidades de refactorización. En este paso, para decidir qué

refactoring utilizar, se puede utilizar como guía la identificación de code smells [33].

La mayoría de los IDEs actuales soportan este enfoque, proveyendo herramientas para la

realizar refactorings de forma semi automática. De esta forma se reducen los tiempos de

debugging y testing [34].

2.3 Code Smells

Debido a que se decidió utilizar un code smell como guía para tomar la decisión de

refactorización, es importante definir qué es un code smell y por qué es importante

identificarlos.

Un code smell surge por la utilización de “malas prácticas” al desarrollar un sistema. Son

decisiones pobres de implementación que hacen que un sistema orientado a objetos sea difícil

de mantener [35]. Son las descripciones generales de código problemático y sirven para

ayudar a los desarrolladores a decidir cuándo un código necesita refactorización [36]. Una

vez aplicado el refactoring apropiado, en la mayoría de los casos se mejoran diversos aspectos

de calidad como mantenibilidad, comprensibilidad y reusabilidad. [37]

Los code smells surgen como una forma de clasificar de una manera lo más precisa posible

los diferentes problemas de diseño que se pueden identificar en un sistema. Dichos problemas

fueron detectados inicialmente por los investigadores como no-conformidad con principios

de diseño, violación de heurísticas de diseño, valores de métricas excesivos, falta de patrones

de diseño o incluso aplicación de anti-patterns [37].

Como se puede inferir, un code smell no es un error y no impide el correcto funcionamiento

de un sistema. Indican problemas de diseño y degradan diversos atributos de calidad,

incrementando el riesgo de costos altos de mantenimiento durante la evolución del sistema o

posibles errores en el futuro.

Page 16: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

16

La forma de eliminar un code smell consiste en la aplicación de un refactoring apropiado,

mejorando la estructura del software sin modificar su comportamiento [37]. Teniendo

conocimiento que los code smells degradan la calidad de un sistema, y sabiendo que el efecto

acumulativo de sucesivos refactorings mejora la calidad del diseño, este tratamiento garantiza

una mejora sustancial en la calidad del código.

En la siguiente tabla se puede visualizar el catálogo de code smells realizado por Lanza y

Marinescu [3]:

Code Smell Descripción God Class Clases que tienden a centralizar la inteligencia del

sistema. Una God Class realiza demasiado trabajo

por sí misma, delegando únicamente los detalles

menores a un conjunto de clases triviales, usando los

datos de otras clases (Normalmente de Data Class).

Feature Envy Métodos más interesados en los datos de otras clases

que en los de su propia clase.

Data Class Clases “tontas” qué funcionan únicamente como

contenedoras de datos, sin ninguna funcionalidad

compleja. Sin embargo otras clases pueden depender

fuertemente de ellas.

Brain Method Métodos extensos que tienden a centralizar la

funcionalidad de una clase.

Brain Class Similar a God Class, con la diferencia de que a pesar

de ser clases excesivamente complejas, no acceden

abusivamente a datos de clases “satélite”.

Significant Duplication Porciones de código que contienen una cantidad

significativa de duplicación.

Intensive Coupling Método que se encuentra sujeto a demasiadas

operaciones en el sistema, y estas operaciones

proveedoras están dispersas en pocas clases.

Dispersed Coupling Similar a Intensive Coupling, pero las operaciones

proveedoras se encuentran dispersas en muchas

clases diferentes.

Shotgun Surgery Método del cual dependen un conjunto amplio de

otras operaciones dispersas en muchas clases. Es el

caso inverso de Dispersed Coupling.

Refused Parent Bequest Hace referencia a clases hijas en una jerarquía de

herencia que no utilizan los métodos declarados por

el padre.

Tradition Breaker Hace referencia a clases que en lugar de especializar

la clase de la cual heredan, simplemente agregan

nuevos métodos que tienen poca relación con

aquellos métodos heredados del padre.

Tabla 2.1: Code Smells catalogados por Lanza y Marinescu

Para poder realizar una refactorización basada en la eliminación de code smells, previamente

deben identificarse los mismos. Una opción es identificarlos automáticamente utilizando

métricas relacionadas.

Page 17: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

17

2.3.1 Feature Envy

Feature Envy puede ser considerado el síntoma más común relacionado con problemas de

acoplamiento y cohesión [38]. Se define como:

“Un método que parece más interesado en los datos de otra clase que en los de su propia

clase” [3].

Este code smell surge cuando el desarrollador viola el principio de agrupar el

comportamiento con los datos relacionados [38]. Estos métodos acceden directamente a

través de métodos accesores (getters) a una gran cantidad de datos de otras clases. Esto

provoca un aumento de “efectos cascada” (el cambio en un método dispara cambios en otros

métodos y así sucesivamente) y disminuye la cohesión de un sistema. La forma de detectarlo

es contar el número de datos externos accedidos, y asegurarse de que los mismos provengan

de pocas clases, o de una única incluso. Las métricas que intervienen en este análisis son

descriptas en la Tabla 2.2 [3]:

Métrica Descripción Acceso a datos extranjeros (ATFD) Indica el uso directo de atributos de otras clases.

Localidad de los accesos a atributos (LAA) Indica la relación entre el acceso a atributos locales

y el acceso a atributos extranjeros.

Proveedores de datos extranjeros (FDP) Indica la cantidad de clases que proveen atributos

extranjeros al método.

Tabla 2.2: Métricas utilizadas por la herramienta

Una vez identificadas las métricas que intervienen, se debe definir un umbral que permita

decidir cuándo se está en presencia de una anomalía. Como se ve en la Figura 2.2, las tres

métricas intervienen en la identificación, y todas deben superar el umbral especificado para

generar una Feature Envy. En caso de que una de las reglas no se cumpla, no se considera la

existencia de este code smell.

Figura 2.2 Detección de Feature Envy

Page 18: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

18

2.3.2 Refactoring de Feature Envy

Los refactorings utilizados para solucionar una Feature Envy son Move Method y Extract

Method. La idea es mover el método que sufre de este code smell a la clase que contiene los

datos que envidia. En primer lugar, se deben identificar los casos en los cuales es conveniente

realizar primero una extracción del fragmento del método que genera la Feature Envy, para

luego mover únicamente ese extracto a la clase correspondiente. De esta forma se encapsulan

los datos y la funcionalidad que manejan esos datos en una misma clase, mejorando la

modificabilidad y mantenibilidad, al tener en una misma ubicación los fragmentos de código

que muy posiblemente se modificarán en conjunto al evolucionar el sistema. De esta forma,

se reduce el nivel de acoplamiento entre clases.

El problema principal al aplicar estos refactorings es la posibilidad de afectar el

comportamiento original del sistema. Si esto llegase a ocurrir, se estaría violando la

definición de refactoring. A la hora de realizar Extract Method, únicamente se pueden extraer

fragmentos de código que mantengan la funcionalidad. Para asegurar esto, se utilizará la

práctica de Program Slicing [8]. En cuanto al uso de Move Method, se controlarán las

dependencias utilizadas por el método antes de realizarlo para no generar errores en el código.

2.3.2.1 Program Slicing

La técnica de Program Slicing es necesaria para realizar Extract Method. Es un método para

descomponer programas automáticamente analizando su flujo de datos y de control. El

programa reducido, llamado “slice”, es un programa independiente que garantiza una

representación fiel del programa original dentro del dominio del subconjunto de

comportamiento especificado [39].

Para mantener el control de flujo y datos, se genera un grafo de dependencias que sirve para

decidir si es posible extraer la porción (slice) de código. Esta técnica busca extraer la porción

más pequeña posible.

Todos estos controles son realizados por la API JDT de Eclipse. Aunque no utiliza la técnica

de Program Slicing directamente, es parte de la aplicación del refactoring considerado en este

informe.

2.3.2.2 Statements

Para realizar Extract Method, se debe dividir el método a nivel statement. Un statement es

una porción del código. El código a extraer debe ser una lista de statements, y no puede

contener ramas de ejecución que continúen por fuera del flujo del código seleccionado. Los

diferentes tipos de statement son: Block, ExpressionStatement, LabeledStatement,

SwitchCase, ForStatement, AssertStatement, EmptyStatement, BreakStatement,

SuperConstructorInvocation, Constructor Invocation, SynchronizedStatement, DoStatement,

LabeledStatement, WhileStatement, TryStatement, ThrowStatement, Variable Declaration

Statement, Return Statement, Type Declaration Statement.

Page 19: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

19

Debido a que un Statement puede contener más Statements dentro de sí mismo anidados, la

forma de obtener todos los Statements de un método es recorrerlos a todos en profundidad

hasta que no queden más nodos por recorrer.

2.3.2.3 Problemática del Move Method

Para realizar satisfactoriamente un Move Method se deben tener en cuenta un conjunto de

precondiciones que aseguren mantener el comportamiento post-refactoring [40]. Entre ellos,

se puede mencionar que la clase a la que se mueve el método no debe contener un método

con el mismo nombre, ni ser declarada como una interfaz. Para una eficaz eliminación de

Feature Envy de un sistema deben satisfacerse todas las precondiciones, de lo contrario no

es aconsejable hacer la recomendación de refactorización de la solución al code smell.

Page 20: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

20

Capítulo 3: Herramientas de refactorización y

análisis de Feature Envy

3.1 Enfoques del refactoring de Feature Envy

Para realizar el refactoring de una Feature Envy, se deben realizar dos pasos fundamentales:

identificar la oportunidad de refactoring, y luego aplicarla. Las herramientas analizadas en

esta sección tienen una particularidad: una vez identificada la Feature Envy, el único

refactoring recomendado y/o aplicado es Move Method. Ninguna herramienta considera una

extracción previa. En cuanto a las posibles acciones realizadas por las herramientas, se

pueden clasificar en tres enfoques:

Recomendación: Las herramientas incluidas en esta categoría sólo encuentran

métodos candidatos y recomiendan la aplicación del refactoring. No distinguen si el

refactoring es posible o si realmente se soluciona la Feature Envy al aplicarlo. En este

grupo se encuentran las herramientas MethodBook, MORE, c-JRecRef y Jmove (las

cuales serán analizadas en este capítulo).

Aplicación: Las herramientas incluidas en esta categoría realizan el refactoring

propiamente dicho, es decir, mueven el método de una clase a otra. No realizan

ningún tipo de análisis o recomendación en cuanto al método que se desea mover,

únicamente realizan el Move Method siempre y cuando se cumpla la regla de no

modificar el comportamiento del sistema ni generar errores de sintaxis. Un ejemplo

representativo de este grupo es la API nativa de Eclipse.

Recomendación y Aplicación: Las herramientas incluidas en esta categoría realizan

por completo el proceso de eliminación de code smells. Son más complejas que las

anteriores, ya que realizan ambos procedimientos e intentan obtener un resultado

válido. Son las únicas que automatizan por completo el proceso de refactorización de

Feature Envy. En este grupo se encuentra únicamente la herramienta JDeodorant.

3.2 Herramientas

En esta sección se presentarán las herramientas mencionadas anteriormente, con el fin de

profundizar el concepto de los enfoques que cada una realiza.

3.2.1 Herramientas de recomendación de refactoring

En esta sección se encuentran las herramientas que encuentran los métodos candidatos a

mover y realizan la recomendación, sin aplicar el refactoring. La mayoría de las herramientas

se encuentran en esta categoría, debido a la complejidad de implementar el refactoring Move

Method.

Page 21: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

21

3.2.1.1 MethodBook

La herramienta MethodBook [40] propone oportunidades de aplicación del refactoring Move

Method con la finalidad de eliminar una Feature Envy.

El enfoque está basado en la técnica probabilística Relational Topic Models (RTM). Consta

de dos pasos: Identificar la “amistad entre métodos” e Identificar la clase envidiada.

El primer paso consiste en extraer la información textual y estructural del código fuente. Toda

esta información se almacena en diferentes matrices que luego son procesadas por el RTM

(Figura 3.1).

Figura 3.1: Proceso utilizado por MethodBook para encontrar recomendaciones

La información textual es representada por palabras en comentarios e identificadores en el

código fuente. Se almacena en la “Matriz de Documento Término a Término”. Es utilizada

por el RTM para definir relaciones semánticas entre métodos y su modelo de distribución.

La información estructural es diversa, por lo cual MethodBook hace un análisis estático para

obtener las dependencias estructurales entre métodos. Almacena los llamados a métodos en

la “Matriz de Interacción de Llamados” y el uso de variables compartidas en la “Matriz de

Datos Compartidos”. Adicionalmente, en la “Matriz de Diseño Original” conserva la

información de a qué clase pertenece cada método, entre otras cosas. Estas matrices

estructurales también son utilizadas para generar el modelo de distribución.

Una vez que posee toda la información, utiliza las matrices de Interacción de Llamados y la

de Datos Compartidos para representar la interacción entre métodos a lo largo de todo el

Page 22: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

22

sistema. La Matriz de Diseño Original permite decidir si un refactoring afectará

positivamente la calidad del diseño del sistema.

Con toda esa información, el RTM genera la “Matriz de Similitud RTM”, que representa la

“amistad entre métodos”, es decir, la cantidad de responsabilidades que comparten todos los

pares de métodos, las estructuras de datos que comparten y la relación que tienen con las

mismas características o conceptos dentro del programa.

Una vez completado el paso de Identificación de Amistad entre métodos, se lo debe llevar a

un ámbito en el cual sea posible detectar una Feature Envy. Para comenzar el proceso de

Identificación de Clase Envidiada se analizan las clases a las cuales pertenecen los “mejores

amigos de cada método”. Si un método en la clase A tiene más amigos en la clase B que en

la propia, se presume que comparte responsabilidades con esta última clase, lo cual podría

indicar la presencia de Feature Envy. Por esta razón, lo que hace MethodBook es identificar

como clase envidiada a la que contenga el mayor porcentaje de métodos amigos. Si la clase

envidiada es la propia, no se sugiere ningún refactoring. Si no es el caso, el último paso es

analizar estáticamente el código para verificar que se cumplan todas las precondiciones que

garanticen mantener el comportamiento original luego de aplicar una operación de

refactoring. En caso de cumplirse, sugiere un refactoring. En caso de no cumplirse, elige

como nueva candidata a la próxima clase con más alto porcentaje de métodos amigos. Este

proceso se repite hasta que se obtiene una clase envidiada que cumpla las precondiciones o

la clase envidiada seleccionada sea la propia.

3.2.1.2 MORE

La herramienta MORE [41] es un recomendador automatizado de refactorings. A diferencia

de MethodBook, no se encarga únicamente de analizar Feature Envy. Posee tres objetivos

principales, los cuales son:

1. Mejorar la calidad de diseño.

2. Resolver code smells.

3. Introducir patrones de diseño.

Para recomendar una operación de refactoring, intenta encontrar el mejor trade-off entre estos

tres objetivos utilizando un algoritmo genético llamado “NSGA-III”.

Como se puede inferir, en este trabajo se va a analizar el segundo objetivo de esta

herramienta, centrándose en el code smell Feature Envy.

El esquema general de MORE se puede ver en la Figura 3.2.

Page 23: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

23

Figura 3.2: Arquitectura del recomendador de refactorings MORE.

El componente llamado Detector de code smells es el encargado de identificar los diferentes

code smells existentes en el código. Utiliza un conjunto de reglas de detección, las cuales

representan diferentes smells, y las expresa como una combinación lógica de límites de

calidad y métricas, es decir, que define los márgenes de aceptación para decidir si el

componente que se está analizando es un code smell.

Las reglas que representan un método que sufre Feature Envy, son las que el autor clasifica

dentro de los tipos “Restricciones de Similitud basadas en Vocabulario” (VS) y

“Restricciones de Similitud basadas en Dependencias” (DS).

El tipo VS se encarga de definir si dos actores tienen vocabularios similares. Es utilizado para

definir la similitud semántica. El proceso para calcularla consiste en tokenizar los nombres

de los métodos, campos, variables, parámetros, tipos, etc., preprocesando indicadores con la

técnica Camel Case Splitter. Luego, se procesa la información obtenida utilizando la técnica

de similitud del coseno, representando a ambos actores como un vector n dimensional, donde

cada dimensión corresponde a un término del vocabulario. Por ejemplo, para dos actores C1

y C2, la ecuación sería la siguiente:

Donde y son los vectores n dimensionales, y los pesos wi se calculan previamente.

El tipo DS contiene las reglas que definen la conexión y la relación semántica entre dos

actores, para proponer refactorings asociados a cercanía semántica. Estas reglas son:

Page 24: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

24

Llamadas compartidas a métodos (SMC): Se calcula utilizando un gráfico de

llamadas, cuyos nodos representan métodos y sus aristas representan llamadas entre

ellos (desde y hacia). Se considera la relación entre dos actores analizando los vecinos

de cada uno de ellos y viendo la relación existente. Se maneja tanto para llamadas

entrantes como salientes. Si se toman dos actores llamados C1 y C2 (clases) las

ecuaciones que defines esta regla son las siguientes:

Se calcula esta métrica usando el promedio entre las dos ecuaciones.

Accesos compartidos a campos (SFA): Se calcula capturando todas las referencias de

los campos usando análisis estático en todo el cuerpo de un método para identificar

dependencias basadas en accesos a los campos (lectura o modificación). Si se

consideran nuevamente los actores C1 y C2, y la función fieldRW(Ci) como aquella

que retorna los campos leídos y modificados por la clase Ci, la forma de calcular esta

regla es la siguiente:

Finalmente, en base a todos los refactorings propuestos, se realiza un cruce para definir

los que se recomendaran efectivamente. Como se indicó anteriormente, para mover un

método, tiene en cuenta los tipos VS y DS:

Page 25: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

25

Tabla 3.1: Selección de refactorings basado en reglas de MORE

El cruce final es definido por el algoritmo genético NSGA-III, y se calcula la cantidad de

code smells resueltos con la siguiente ecuación (no hace un cálculo específico para

Feature Envy):

3.2.1.3 c-JRefRec

La herramienta c-JRecRef [42] es una herramienta de recomendación de oportunidades para

la aplicación del refactoring Move Method.

El enfoque de la misma tiene como principal objetivo tener en cuenta la semántica del código,

además del análisis de métricas para medir la efectividad de las recomendaciones.

Adicionalmente, se encarga de detectar las oportunidades de refactoring a medida que el

programador compila su código, basándose en los cambios introducidos por el mismo.

En primera instancia, utiliza el AST Parser del Eclipse Java Development Tools (JDT) para

analizar las relaciones entre clases y métodos. En base a ellas, realiza un grafo direccionado

de dependencias G = (V, E) donde los vértices V representan los métodos y campos de un

programa y las aristas E representan dependencias (llamados a métodos y acceso a campos)

entre ellos. Adicionalmente, obtiene la información semántica utilizada para la

recomendación extrayendo todos los identificadores, incluyendo nombres de paquetes,

clases, métodos, atributos, y parámetros para cada clase.

A su vez, provee 2 vistas para su análisis. La vista Class State View (Figura 3.3) es utilizada

para ver el estado de las clases antes y después de la aplicación de un refactoring.

Page 26: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

26

Figura 3.3: Vista Class State View de la herramienta c-JRefRec

Para cada clase, provee 4 columnas con información relevante al análisis de oportunidades

de refactoring:

1. methods(C): Indica la cantidad de métodos definidos en la clase C.

2. edges(C): Indica la cantidad de aristas entrantes y salientes de la clase C.

3. clients(C): Indica la cantidad de clases que utilizan métodos o campos de la clase C.

4. dependents(C): Indica la cantidad de métodos o campos de otras clases accedidos

por la clase C.

Esta vista se refresca automáticamente al guardar/compilar el código fuente, y muestra en

rojo los cambios introducidos para cada indicador en relación al último estado guardado.

Adicionalmente, la herramienta provee una segunda vista llamada Refactoring Candidates

View (Figura 3.4) la cual presenta el método candidato a ser movido, la clase a la cual

debería ser movido y las métricas relacionadas para ayudar al desarrollador a tomar la

decisión.

Figura 3.4: Vista Refactoring Candidates View de la herramienta c-JRecRef

La forma de seleccionar las clases candidatas a ser movidas está dada por la similitud

semántica entre dos clases y por el análisis de dependencias.

Page 27: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

27

La similitud semántica entre un método m y una clase c se calcula mediante la fórmula

SS(m, c) = cos(tf -idf(m),tf -idf(c)) utilizando los vectores tf-idf donde los métodos y las

clases son considerados como documentos individuales.

El análisis de dependencias se realiza teniendo en cuenta 3 factores:

1. Δedges(R, C): Es el número de aristas agregados/eliminados de la clase C al aplicar el

refactoring R.

2. Δclients(R, C): Es el número de clases clientes agregadas/eliminadas al aplicar el

refactoring R.

3. Δdependents(R, C): Es el número de dependencias agregadas/eliminadas al aplicar el

refactoring R.

En base a estos 3 indicadores y a la semántica, se definen las oportunidades de aplicación

de Move Method utilizando la siguiente función:

Δedges(R,Coriginal) + Δedges(R,Ctarget) + Δclients(R,Coriginal) + Δclients(R,Ctarget) +

Δdependents(R,Coriginal) + Δdependents(R,Ctarget) < 0 AND SS(m, Coriginal) < SS(m,Ctarget).

Con la presentación de las clases candidatas, concluye el flujo de c-JRecRef, y queda como

responsabilidad para el programador la aplicación o no de los refactorings recomendados.

3.2.1.4 JMove

La herramienta JMove [42] es un recomendador de oportunidades para la aplicación del

refactoring Move Method. Tiene la particularidad de ser más simple que las herramientas

anteriormente analizadas, y de no analizar en ningún momento el impacto de sus

recomendaciones sobre el code smell Feature Envy.

JMove utiliza un coeficiente de similitud, de esta forma, si identifica un método más similar

a una clase que a la clase en la que se encuentra, recomienda la aplicación del refactoring. El

esquema general del algoritmo utilizado consiste en la comparación entre la similitud de un

método f, la clase C en la que se encuentra y la similitud de dicho método con las demás

clases Ci del sistema:

Para lograrlo, la solución se encuentra implementada en 3 módulos:

Módulo de creación de dependencias: Establece la dependencia estructural entre un

método y una clase. Para cada método, establece la cantidad de llamados realizados

por la clase, acceso a atributos e instanciación de variables.

Page 28: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

28

Módulo de cálculo de similitud: Para definir la similitud entre dos métodos f’ y f’’ se

utiliza la siguiente función:

donde a es el número de dependencias comunes a los 2 métodos, b es el número de

dependencias que únicamente se encuentran en el método f' y c es el número de

dependencias que únicamente se encuentran en el método f’’. S(f’,f’’) = 1 indica

similitud máxima y S(f’,f’’) = 0 indica que los métodos no tienen dependencias en

común. La forma que utiliza la herramienta para detectar la similitud entre un

método f y una clase C consiste en calcular la media aritmética de la similitud entre

f y todos los métodos de C.

Módulo de recomendación: Finalmente, dado el conjunto de clases T, la función

best_class(f, T) indica la clase más apropiada, es decir, la que posee mayor similitud

con el método.

Como se puede ver en la Figura 3.5, una vez realizado el análisis, JMove presenta los

resultados en la interfaz de Eclipse, indicando la clase candidata a refactorizar y la clase

destino propuesta por el recomendador.

Figura 3.5: Interfaz de JMove

3.2.2 Herramientas de aplicación de refactorings

En esta sección se encuentran las herramientas que implementan el refactoring Move

Method, sin realizar ningún tipo de recomendación o análisis en cuanto al método que se

desea mover, simplemente controlan las precondiciones necesarias para asegurar que no se

modifique el comportamiento de sistema y no se introduzcan errores de sintaxis.

Page 29: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

29

3.2.2.1 Eclipse

La API nativa de Eclipse, posee la capacidad de realizar el refactoring Move Method. Es

importante aclarar que no hace ninguna recomendación, simplemente realiza la operación

on-demand.

Al intentar realizar un Move Method, en primera instancia analiza un conjunto de

precondiciones para garantizar la no modificación del comportamiento original del sistema

y la no generación de errores de sintaxis. Entre las más comunes, se encuentran la no

existencia de llamados recursivos y la comprobación de que el método no esté definiendo un

método abstracto en la jerarquía de herencias.

Posteriormente, Eclipse presenta las clases hacia las cuales es posible mover el método.

Únicamente tiene en cuenta las clases de los parámetros del mismo, y de variables de

instancia usadas. En caso de no existir parametrización o uso de variables de instancia, no se

permite realizar el Move Method al no tener candidatos.

3.2.3 Herramientas de recomendación y aplicación de

refactorings

En esta sección se encuentran las herramientas que realizan por completo el proceso de

eliminación de code smells, es decir, se encargan de recomendar posibles refactorings y

aplicarlos en caso de ser seleccionados. Son las únicas que automatizan por completo el

proceso de refactorización de Feature Envy.

3.2.3.1 JDeodorant

JDeodorant [25] es la única herramienta que actualmente se encarga de identificar,

recomendar y aplicar el refactoring Move Method para la resolución del code smell Feature

Envy. A diferencia de los recomendadores analizados anteriormente (sección 3.2.1), este

plugin de Eclipse no realiza un complejo análisis para la recomendación, simplemente utiliza

el ASTParser del Eclipse Java Development Tool (JDT) para analizar las relaciones entre

entidades y aplicar el refactoring.

El verdadero aporte de esta herramienta es la aplicación correcta del refactoring Move

Method al realizar una completa pre-evaluación de todos los posibles impactos sobre la

calidad del diseño del sistema y aplicar la más efectiva.

La forma de utilizar la herramienta es relativamente sencilla. Se debe abrir la ventana de

navegación para Identificar los code smells. Luego se accede a la pestaña específica de

Feature Envy para poder visualizar los refactorings propuestos por la herramienta, y

aplicarlos posteriormente desde el botón Aplicar Refactorings, como se ve en la Figura 3.6.

Page 30: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

30

Figura 3.6: Presentación de Feature Envy de JDeodorant

Como se puede ver, la herramienta propone un ranking de refactorings a aplicar. Para

completar el proceso, se puede seleccionar un refactoring propuesto y presionar el botón

“Apply Refactoring” para implementar la solución sugerida.

Al realizar un análisis del código interno de JDeodorant, se puede apreciar que la

comprobación de pre-condiciones para realizar un Move Method es extremadamente

compleja y tiene en cuenta todos los inconvenientes posibles que podrían imposibilitar su

aplicación.

Finalmente, se ha comprobado que la recomendación y aplicación se condice con la

propuesta por diferentes autores, por los que esta herramienta, a nivel de refactoring de

Feature Envy, se considera correcta y de alta utilidad.

3.3 Criterios de comparación

En esta sección se definen los criterios para realizar la comparación entre las distintas

herramientas analizadas en la sección 3.2.

Categoría de la herramienta: se categoriza cada herramienta según la etapa de

refactoring que soluciona.

Una vez categorizada, se tienen en cuenta los siguientes criterios:

o Solución de Feature Envy: Define si la herramienta intenta solucionar el code

smell o no.

o Tipo: Define si la herramienta requiere asistencia del programador en alguna

de sus fases (automática o semi-automática)

o Errores post-refactoring: Define si la herramienta introduce errores de

compilación o cambia el funcionamiento del sistema.

Page 31: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

31

3.3.1 Comparación y conclusiones

En la Tabla 3.2 se muestra cada categoría y la etapa de refactoring que intenta solucionar. La

mayoría de las herramientas disponibles se centran en la recomendación del refactoring Move

Method, debido a que existe muy poco soporte en la API de Eclipse para su implementación.

Únicamente JDeodorant aplica automáticamente este refactoring al realizar una compleja

implementación del análisis completo de pre-condiciones que se deben cumplir para poder

realizar el refactoring. Sin embargo, esta herramienta no se centra en un análisis complejo

para la recomendación, por lo que en muchas ocasiones no provee una recomendación óptima

para aplicar el refactoring Move Method.

Herramienta Enfoque de

recomendación

de Move

Method

Enfoque de

aplicación

de Move

Method

Enfoque de

recomendación

y aplicación de

Move Method

Sección

JDeodorant X 3.2.3

JMove X 3.2.1

MORE X 3.2.1

MethodBook X 3.2.1

c-JRecRef X 3.2.1

Nativa del IDE Eclipse X 3.2.2

Tabla 3.2: Categorías de las herramientas

En la Tabla 3.3 se pueden ver las herramientas junto con las prestaciones que proveen. Se

pueden encontrar datos sobre el enfoque de solución de Feature Envy, la participación del

desarrollador en el proceso de refactoring y los errores que introducen las herramientas al

realizar el refactoring.

Herramienta Soluciona

Feature Envy

Automática / Semi -

Automática

Errores post

refactoring

JDeodorant Sí Automática Sí

JMove No Semi-Automática No

MORE No Semi-Automática No

MethodBook No Semi-Automática No

c-JRecRef No Semi-Automática No

Nativa del IDE Eclipse No Semi-Automática No

Tabla 3.3: Características de las herramientas

Solo JDeodorant intenta solucionar automáticamente las Feature Envys detectadas en un

proyecto debido a que posee un enfoque de recomendación y aplicación de Move Method.

Esto se encuentra muy relacionado a la intervención del desarrollador en el proceso. La gran

mayoría de las herramientas tienen un enfoque orientado a facilitar la tarea del programador

mediante la identificación de oportunidades de refactoring. Sin embargo, no aplican

automáticamente el refactoring Move Method, por lo cual el programador está obligado a

Page 32: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

32

mover manualmente el método seleccionado y realizar el control de dependencias,

asegurándose de no modificar el comportamiento del sistema. Es por esto que las demás

herramientas se consideran semi-automáticas, debido a que no pueden completar el proceso

sin la intervención del desarrollador.

La columna de errores post-refactoring muestra cuales son las herramientas que introducen

errores al aplicar el refactoring. JDeodorant es la única que lo hace debido a que es la única

que aplica el refactoring luego de una recomendación. A pesar de poseer un completo control

de pre-condiciones, se detectaron casos en los cuales genera errores detectables en tiempo de

compilación luego de realizar un Move Method. Por su parte la API Nativa de Eclipse, a

pesar de aplicar el refactoring, es más restrictiva y no permite la aplicación de Move Method

si detecta que se va a introducir un error.

A partir del análisis de los datos se puede determinar que las propuestas se centran en

identificar oportunidades del refactoring Move Method sin tener en cuenta la eliminación de

Feature Envy. Adicionalmente, se puede señalar que las herramientas recomiendan mover el

método completo a la clase candidata. Por esta razón, resulta interesante plantear un enfoque

que intente realizar una extracción previa al Move Method, para eliminar una Feature Envy

moviendo a la clase candidata únicamente las porciones de código que generan esta anomalía

de diseño.

Page 33: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

33

Capítulo 4: Un enfoque iterativo para la

refactorización de Feature Envy

4.1 Refactorización de Feature Envy

Es común que con el paso del tiempo se degrade la calidad de un sistema, debido a los

cambios paulatinos que los desarrolladores deben introducir durante la evolución del

software, ya que muchas veces se realizan sin el total conocimiento de la arquitectura del

sistema y de sus requerimientos iniciales. El uso de malas prácticas, denominadas code

smells, ha sido establecido como un concepto para identificar patrones o aspectos del diseño

de software que pueden causar problemas para el desarrollo o el mantenimiento del sistema

[32].

Uno de los 21 code smells catalogados por Lanza y Marinescu [3] es Featury Envy. Este code

smell indica la existencia de métodos que parecen más interesados en los datos de otras clases

que en lo de su propia clase. Estos métodos acceden directamente o vía métodos accesores a

una gran cantidad de datos de otras clases [3]. Esto puede ser una señal de que el método está

ubicado en un lugar incorrecto y debe ser movido a otra clase.

Es necesario refactorizar las Feature Envy para mejorar la cohesión y evitar los “efectos

cascada” [3]. Es importante poner en una misma clase las cosas que cambiarán juntas [2].

Adicionalmente, la existencia de Feature Envy está relacionada directamente con la

existencia de otros code smells como God Class o Data Class (Figura 4.1), por lo que es

posible eliminar otros code smells al solucionar las Feature Envy de un sistema.

Figura 4.1 Correlación entre code smells. Lanza y Marinescu [3].

En este trabajo se propone un enfoque para la eliminación de las Feature Envy de un sistema

que facilite su evolución y mantenimiento. El enfoque consiste en el análisis del código de

Page 34: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

34

un método identificado como Feature Envy para definir si es posible mover el mismo o un

fragmento del mismo a una clase candidata, y luego la aplicación automática de dichas

acciones. Estas acciones conllevarán a la eliminación del code smell, aumentando la

modificabilidad y extensibilidad del sistema. Además, se permite la visualización de las

soluciones generadas para que el desarrollador pueda analizarlas, observando las métricas

propuestas, y así encontrar la más adecuada para luego aplicar al proyecto.

En la resolución del code smell Feature Envy intervienen 2 refactorings diferentes: Extract

Method para obtener el fragmento de código y Move Method para moverlo a la clase a la que

debería pertenecer. Estos refactorings no son triviales debido al conjunto de precondiciones

a tener en consideración para no modificar la funcionalidad del sistema. Por ejemplo, para el

refactoring Move Method, se deben tener en cuenta un conjunto de precondiciones para

definir si es posible la aplicación del mismo

1. La clase objetivo no debe heredar un método que posea el mismo nombre que el

método a mover.

2. El método a ser movido no debe sobreescribir un método heredado en su clase

original.

3. El método a ser movido no debe ser synchronized.

4. El método a ser movido no debe contener asignaciones a campos de la clase origen

(incluyendo campos heredados).

5. El método a ser movido debe tener una relación uno a uno con la clase objetivo.

Es importante tener en cuenta estos factores para la aplicación del enfoque propuesto.

4.2 Esquema general de la solución iterativa de Feature Envy

El enfoque para la refactorización sigue un ciclo iterativo donde la entrada es una Feature

Envy y la salida es un conjunto de soluciones a la misma en caso de existir. Estas soluciones

son el conjunto de refactorings realizados junto con sus métricas asociadas.

Este enfoque consta de 6 actividades, aunque dependiendo las características del método,

puede requerir actividades adicionales para realizar extracciones.

1. Obtener características del método: Esta actividad recibe como entrada un método

el cual ha sido identificado previamente como Feature Envy. El objetivo de esta

actividad es recuperar las características específicas del método que ayudarán a

decidir cuál será la mejor forma de refactorizarlo.

2. Elegir las clases candidatas: En esta actividad se definen cuáles son las clases de las

cuales envidia el método, y se las prioriza para seleccionar las candidatas a las cuales

se moverá el método o un fragmento del mismo. El objetivo de esta actividad es

seleccionar las clases más apropiadas para intentar asegurar la eliminación de la

Feature Envy, de lo contrario puede ocurrir que la Feature Envy siga existiendo en la

nueva clase.

Page 35: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

35

3. Seleccionar el fragmento de código a mover: En esta actividad se decide cuál es el

fragmento del método que no corresponde a la clase en la que se encuentra. Utilizando

la información obtenida en el paso 1, se puede decidir por no extraer ningún

fragmento del método y moverlo completamente. Finalmente, se aplican los

refactorings seleccionados solucionando de esta manera la Feature Envy.

4. Calcular métricas de la solución generada: Una vez encontrada la solución, se

procede con esta actividad, que consiste en calcular las métricas del código

pertinentes a la existencia de Feature Envy. De esta forma, el desarrollador puede

evaluar la calidad de la solución y definir si le parecen aceptables los valores

obtenidos.

Como se ve en la Figura 4.2, el proceso itera en las actividades 3 y 4 hasta encontrar

soluciones o hasta agotar las clases que pueden ser consideradas como candidatas para

realizar el refactoring.

Figura 4.2: Esquema general de la solución de Feature Envy.

Como se puede observar, se itera por cada clase candidata seleccionando el fragmento de

código a mover recomendada, acompañando cada solución con sus métricas. En este punto

se pueden dar 3 escenarios:

Page 36: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

36

No se encontró solución a la Feature Envy.

El programador no desea aplicar ninguna solución propuesta.

El programador elige una solución.

Los primeros dos escenarios conllevan a la finalización del flujo de ejecución, dando como

resultado la no refactorización del code smell Feature Envy. El tercer caso permite continuar

el flujo con las últimas dos actividades:

5. Aplicar el refactoring: Cuando el desarrollador selecciona la solución que considera

más óptima, se procede a la aplicación efectiva de los refactorings que generan dicha

solución.

6. Corregir errores: Esta actividad es la única que queda completamente a cargo del

desarrollador. Se debe verificar si el refactoring Move Method ha introducido algún

error de código detectable en tiempo de compilación y corregirlo.

En cada iteración, se deben priorizar de manera lo más precisa posible las clases candidatas,

y seleccionar el mejor statement a extraer (o el método completo) para iterar la menor

cantidad de veces posible. La selección de clase se prioriza utilizando la métrica ATDF,

mientras que la selección de statement es dependiente de la heurística utilizada.

De esta forma, se itera hasta agotar las clases que pueden ser candidatas.

Para la aplicación de este enfoque, se optó por extender la herramienta Bandago [20]

perteneciente al plugin JSpIRIT [13] de Eclipse. Por lo tanto, la solución presentada es

aplicada para el lenguaje Java. JSpIRIT analiza código estáticamente y provee el método

catalogado como Feature Envy que se utiliza de entrada. Bandago provee la estructura

general para poder cumplir el ciclo de ejecución y presentar los resultados obtenidos de una

forma sencilla.

4.3 Desarrollo del enfoque iterativo para la refactorización de

Feature Envy

A continuación se detalla cada actividad involucrada en el enfoque junto con un ejemplo

guía. Este ejemplo consiste en un método afectado por el code smell Feature Envy y un

seguimiento de cada uno de los cambios realizados por cada actividad sobre el código Java

del mismo.

4.3.1 Actividad 1: Obtener características del método

Esta actividad recibe como entrada un método catalogado como Feature Envy. Esta entrada

es provista por la herramienta JSpIRIT. Como se ve en la Figura 4.3, JSpIRIT presenta una

lista de code smells junto con el método Java asociado. Se tomará como ejemplo el método

mapEntry perteneciente a la clase OptionsService tomado de la aplicacion jMoney, uno de

los casos de estudios analizados.

Page 37: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

37

Figura 4.3: JSpIRIT Smells View

Como se puede ver en la Figura 4.3, se identifican diferentes tipos de code smells, y es el

usuario el que debe seleccionar la Feature Envy que servirá como entrada para la

refactorización. Para realizar esta acción, se utilizará la interfaz de la extensión de JSpIRIT,

llamada Bandago, la cual permite seleccionar un método afectado por un code smell y aplicar

un refactoring en caso de ser posible.

En esta actividad, se identifican todos los llamados a métodos propios y uso de variables de

instancia de la clase origen. En la Figura 4.4 se muestra la identificación variables de

instancia.

Figura 4.4: Llamados a variables de instancia de la propia clase del método ejemplo.

Al observar el método se puede definir que utiliza variables de instancia. Las variables

utilizadas son “entryStates”, “entryToOldCategoryMap” y “em”. Esta detección es realizada

mediante la interfaz provista por JSpIRIT. Al analizar la métrica Locality of Attribute

Accesses (LAA), la cual establece el porcentaje de uso de atributos locales, se define que se

Page 38: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

38

están utilizando variables de instancia cuando dicha métrica es mayor a cero. Esta métrica se

calcula utilizando la siguiente fórmula:

Para el ejemplo presentado, el número de accesos a variables de instancia es 3, debido a que

se contabilizan los 3 accesos señalados en la Figura 4.4. En cuanto al número total de accesos,

se deben sumar los 3 accesos a variables de instancia y todos los accesos a parámetros y

variables locales del método. En este caso, se deben sumar todos los accesos a los parámetros

“e” y “oldEntry”, dando como resultado un total de 19 accesos. De esta forma, al reemplazar

en la ecuación presentada, puede observarse que la métrica LAA posee un valor mayor a 0:

El análisis de esta información para definir el refactoring a utilizar se realizará

posteriormente en la actividad 3.

4.3.2 Actividad 2: Elegir la clase candidata

Una vez identificadas las características del método, se procede a identificar la clase

candidata a la cual se debe mover el método. Con este objetivo, nuestro enfoque utiliza la

métrica Access to Foreign Data (cantidad de atributos de otras clases que utiliza el método)

debido a que se encuentra directamente relacionada con la existencia de Feature Envy. La

misma se obtiene calculando el número de llamados directos o indirectos (vía métodos getters

y setters) a campos de clases externas.

Teniendo en cuenta esta métrica, se analizan en profundidad las incidencias que generaron

que el valor de la misma supere el umbral considerado como normal, es decir, se contabiliza

la cantidad de llamados a clases externas. De esta forma, al identificar individualmente los

accesos a atributos o métodos de otras clases, se puede definir cuál es la clase que posee más

accesos utilizados por el método. Se seleccionó esta métrica porque, de las métricas

relacionadas con Feature Envy definidas por Lanza y Marinescu [3], es la que se encuentra

directamente relacionada con las clases utilizadas en exceso por el método, provocando el

code smell Feature Envy.

Page 39: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

39

Figura 4.5 Identificación de llamados a clases externas

La Figura 4.5 muestra la identificación de llamados a clases externas involucradas en el

ejemplo presentado. Para obtener el valor de la métrica ATFD se debe contabilizar el total

de dichos llamados, por lo cual el valor de la misma para el ejemplo presentado es 17. Se

puede observar que se debió detallar el path completo de las clases externas que intervienen

debido a que poseen el mismo nombre. Para definir las clases que pueden ser consideradas

candidatas, se calcula el valor de la métrica ATFD para cada una de las clases extranjeras

involucradas.

Ranking Nombre de la clase Nombre del

parámetro

Valor ATDF

1 name.gyger.jmoney.model.Entry e 9

2 net.sf.jmoney.model.Entry oldEntry 8

Tabla 4.1: Priorización de clases externas accedidas por la Feature Envy

Como se detalla en la Tabla 4.1, se considera la clase name.gyger.jmoney.model.Entry como

la clase más envidiada (primera en el ranking) al ser la que recibe la mayor cantidad de

llamados por parte del método catalogado como Feature Envy. Al analizar el valor de ATDF,

se puede observar que la cantidad de llamados a net.sf.jmoney.model.Entry también es

significativa.

4.3.3 Actividad 3: Seleccionar el fragmento de código a mover

En esta actividad se utiliza la información obtenida en la actividad 1 (Sección 4.3.1) para

definir cuál es el fragmento del método que no corresponde a la clase en la que se encuentra.

Es decir, se analizarán las características propias del método para tomar la decisión.

El primer aspecto a tener en cuenta es si el método analizado utiliza variables de instancia de

su propia clase. El motivo de este control está dado por la posibilidad de no eliminar la

Feature Envy al mover el método a la clase candidata, debido a que los accesos a llamados

Page 40: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

40

de variables de instancia de la clase en la cual se encuentra el método generen una Feature

Envy al encontrarse en una nueva clase.

En caso de no utilizar ninguno, se considera que el método puede ser movido completamente

a la clase candidata seleccionada en la actividad anterior (Sección 4.3.2) y la actividad actual

finaliza.

En caso de existir algún acceso a variables de instancia de la clase, se debe seleccionar el

fragmento de código del método que al ser movida de la clase original, elimina la existencia

de la Feature Envy identificada sin generar este code smell en la nueva clase. Para lograr este

objetivo, se optó por la utilización de una heurística que consta de dos pasos:

1. Identificar la primera y última ocurrencia de un llamado a un método o atributo de la

clase candidata.

2. Seleccionar el statement o conjunto de statements más pequeño que contiene ambos

llamados. Este paso evita la rotura de flujos de control, por ejemplo, cortar una

sentencia IF a la mitad.

Figura 4.6: Selección de statement o conjunto de statements a extraer

Como se ve en la Figura 4.6, estos pasos se repiten para cada clase candidata identificada.

Para el método ejemplo, esta actividad genera dos resultados. El primero se encuentra

detallado en la Figura 4.7.

Page 41: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

41

Figura 4.7: Selección del statement candidato a ser extraído para la clase

name.gyger.jmoney.model.Entry

Como se puede observar, en este caso la primera y última ocurrencia no se encuentran en

ningún flujo de control, por lo cual es posible seleccionar un statement que comience en la

primera ocurrencia y termine en la última. Otro factor importante es la existencia de una

variable de instancia de la clase original en dicho statement, pero se puede corroborar

analizando la métrica LAA (Locality of Atribute Acceses) que la relación entre el uso de

variables locales y llamados externos no es significativa. Su cálculo se obtiene mediante la

siguiente ecuación:

Para el statement del ejemplo, el número de accesos a variables de instancia es 1, ya que

únicamente se realiza un acceso a la variable de instancia entryStates. En cuanto al número

total de accesos, se incluye el acceso antes mencionado y todos los llamados a métodos de

los parámetros e y oldEntry, dando como resultado un total de 16 accesos.

De esta forma, se visualiza que el statement seleccionado se sigue encontrando en los límites

establecidos por Lanza y Marinescu [3] (LAA < ONE THIRD), y se procede a seleccionarlo

como candidato a ser extraído.

4.3.4 Actividad 4: Calcular las métricas de la solución generada

Una vez seleccionado el fragmento de código que debe ser movido a la clase candidata, el

objetivo de esta actividad es analizar el fragmento seleccionado para el cálculo de métricas.

Para lograr este objetivo, se procede a realizar una copia de la clase objetivo. En esta copia

se aplicará el refactoring Move Method del fragmento seleccionado para poder calcular las

métricas sin afectar la clase original. Una vez realizado el cálculo, la copia es eliminada del

proyecto.

Page 42: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

42

Las métricas permiten al desarrollador evaluar la calidad de cada solución. Las métricas

calculadas son las tres asociadas a la existencia de Feature Envy (ATFD, LAA y FDP). La

métrica Access to Foreign Data (ATFD) indica el uso directo de atributos de otras clases. La

métrica Locality of Attribute Accesses (LAA) indica la relación entre el acceso a atributos

locales y el acceso a atributos extranjeros. Finalmente, la métrica Foreign Data Providers

(FDP) indica la cantidad de clases que proveen atributos extranjeros al método.

En la Figura 4.8 se observa el cálculo de las métricas de la solución generada. Al comparar

los valores del método original con los de la solución propuesta, se puede observar que la

métrica ATDF disminuyó su valor considerablemente. Esto se debe a que una gran parte de

los accesos a clases extranjeras (los cuales se contabilizan para obtener el valor de esta

métrica) pertenecen a la clase a la cual se moverá el método, por lo que dichos llamados

dejarán de ser extranjeros y pasarán a ser locales a la clase en la que se encuentran. Por esta

misma razón, la relación entre número de accesos locales y número total de accesos aumenta,

dando como resultado un valor más elevado al calcular la métrica LAA. El valor de la métrica

FDP disminuye al reducirse el número de clases extranjeras utilizadas por el método.

Figura 4.8: Cálculo de las métricas de la solución generada (Bandago View)

El análisis que debe realizar el desarrollador debería basarse en los siguientes conceptos:

ATFD: Se debe considerar positiva la disminución del valor de esta métrica. Esto

implicaría que la solución accede a una menor cantidad de datos de clases externas.

LAA: Se debe considerar positivo el aumento del valor de esta métrica. Esto

implicaría que la solución utiliza un mayor porcentaje de variables propias en relación

al uso total de variables.

FDP: El aumento significativo en el valor de esta métrica implica la eliminación de

la Feature Envy. Esto se debe a que el uso de variables y métodos externos no se

concentraría únicamente en un pequeño número de clases.

4.3.5 Actividad 5: Aplicar el refactoring

Esta actividad consiste en la aplicación efectiva de la solución seleccionada.

Una vez presentadas las métricas para las soluciones generadas, el desarrollador podrá

seleccionar una de ellas para la aplicación efectiva del refactoring. La herramienta se encarga

de mostrar a la izquierda el método original y a la derecha el fragmento de código que se

extraerá.

Page 43: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

43

Figura 4.9: Selección de una solución para Feature Envy (Bandago Wizard)

De esta forma, el desarrollador puede ver aplicada la solución propuesta, en la cual se extrae

el statement o conjunto de statements identificados por la actividad 3.

4.3.6 Actividad 6: Corregir errores

Esta actividad es la única que queda completamente a cargo del desarrollador. Se debe

verificar que la aplicación del refactoring Move Method no haya introducido errores de

código detectables en tiempo de compilación.

Figura 4.10: Método movido a la clase candidata

En la Figura 4.10 se puede ver que el refactoring ha introducido un error detectable en tiempo

de compilación a causa del llamado a una variable de instancia de la clase original. Queda a

cargo del desarrollador la corrección de ese error para completar el refactoring.

Page 44: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

44

4.4 Implementación de la solución

En esta sección se describen los aspectos relevantes involucrados en la implementación de la

solución.

4.4.1 Aplicación de refactorings

Para el caso de Extract Method, JDT ya tiene implementado el control de precondiciones

necesarias para decidir si es posible la aplicación del refactoring sin introducir errores de

compilación o modificar el comportamiento del sistema.

Para el caso de Move Method, es insuficiente depender únicamente del conjunto de

precondiciones establecidas por el IDE Eclipse. Esto se debe a que Eclipse implementa

precondiciones débiles para este refactoring [44, 45, 46]. Se denominan precondiciones

débiles cuando el conjunto de precondiciones implementadas son insuficientes para

garantizar la preservación del comportamiento del sistema al aplicar un refactoring. Por esta

razón, es necesario analizar las cinco precondiciones adicionales propuestas por la

herramienta JDeodorant y mencionadas por Sales et al. [47]:

1. La clase objetivo no debe heredar un método que posea el mismo nombre que el

método a mover.

2. El método a ser movido no debe sobreescribir un método heredado en su clase

original.

3. El método a ser movido no debe ser synchronized.

4. El método a ser movido no debe contener asignaciones a campos de la clase origen

(incluyendo campos heredados).

5. El método a ser movido debe tener una relación uno a uno con la clase objetivo.

Este enfoque propone encapsular el Move del método realizando un Extract Method en todas

las situaciones, incluso cuando se pretende mover completamente el método. En la Figura

4.11 se presenta un ejemplo de la refactorización realizada por el enfoque propuesto. En la

parte izquierda se puede ver el método original. Este es el código analizado por JSpIRIT, el

cual es enviado a Bandago para hallar un conjunto de soluciones. En la parte derecha de la

figura se puede ver el fragmento de código extraído por la heurística y cómo este es

reemplazado en el método original. En lugar de mover el método completo a la clase

candidata, se realiza un extract previo que previene los conflictos señalados en las

precondiciones 1 y 2, así como inconsistencias en los llamados ya existentes a dicho método

en todo el sistema, debido a que el método original conserva el mismo nombre.

Page 45: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

45

Figura 4.11: Extracción de un método previo a ser movido.

En cuanto a la precondición 4, este escenario particular introduce errores detectables en

tiempo de compilación que deben ser solucionados manualmente por el desarrollador. Estos

errores se consideran aceptables con el objetivo de restringir una menor cantidad de

refactorizaciones. Estos casos se analizarán en profundidad durante el desarrollo del enfoque,

debido a que la corrección de errores es una actividad contemplada por el esquema de la

solución planteada.

Con respecto a las precondiciones 3 y 5, no se realizó ningún control debido a la dificultad

que plantea la detección de estos escenarios.

4.4.2 Vista arquitectónica de Bandago

Se presenta en la Figura 4.12 un diagrama de contexto [43] de Bandago. JSpIRIT detecta los

Code Smells de un proyecto, priorizados según su importancia de refactorización. De este

conjunto de Code Smells, el desarrollador selecciona uno para hallar las posibles soluciones.

La Figura 4.12 describe la interacción entre JSpIRIT y Bandago en el caso que el Code Smell

seleccionado sea una Feature Envy. El sistema solo recibe como entrada la Feature Envy

seleccionada por el desarrollador. Luego, el desarrollador elige una de las soluciones

provistas para aplicar efectivamente en el código original, generando una solución final al

problema seleccionado con anterioridad en la herramienta JSpIRIT.

Page 46: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

46

Figura 4.12: Diagrama de contexto de Bandago.

La Figura 4.12 presenta una visión de la arquitectura de Bandago usando la vista de

componentes y conectores [43]. Todos los componentes de este proyecto se ejecutan

utilizando la plataforma Eclipse como soporte.

En el catálogo de elementos de la tabla 4.2 se detalla cada elemento de la arquitectura

representado en la vista.

Elemento Descripción

JSpIRIT Esta es una herramienta externa que se encarga de encontrar todos

los Code Smells de un sistema.

Bandago genera una extensión a una vista de esta herramienta y se

acopla a su vista.

Eclipse JDT Es la plataforma brindada por Eclipse para poder generar,

comprobar y ejecutar una refactorización al código Java. Se encarga

de la modificación directa de la ICompilationUnit.

Eclipse Platform Eclipse es una plataforma de integración de herramientas de código

abierto. Esta contiene un ambiente de desarrollo de programación

Java ofreciendo un alto nivel de productividad y flexibilidad.

Además, puede ser ejecutado en una gran variedad de sistemas

operativos. Bandago fue desarrollado sobre Eclipse.

Page 47: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

47

Eclipse Platform

Runtime

Execution

Eclipse provee el runtime event manager para el manejo y control

de las interfaces de usuario. El mismo implementa el estilo

arquitectónico implicit invocation. Cuando el event manager

publica un evento generado por una acción de usuario como un

click de un botón, draganddrop, etc., entonces los componentes que

están suscritos a estos eventos serán invocados y activados.

Bandago

Refactoring Core

Este componente contiene toda la funcionalidad para soportar el

enfoque de eliminación del Code Smell Feature Envy, generando

varias soluciones al problema mediante el uso de una heurística que

respeta una interfaz. De esta manera, se brinda la posibilidad de

desarrollar distintas heurísticas a futuro y poner el foco en distintas

estrategias para analizar el Code Smell. En base a esto, se puede

decidir el fragmento de código a extraer. La idea principal es

desacoplar el análisis que se realiza para decidir el fragmento de

código a mover, de todo lo necesario para realizar el refactor

propiamente dicho, dando la posibilidad de analizar el code smell

desde diferentes enfoques.

Cuando se quiere eliminar las Feature Envy de un proyecto se

interactúa con la herramienta JSpIRIT para obtener todos los Code

Smells y luego con la User Interface views & controls se solicita

cuál de estas desea eliminar. Luego se muestran en otra vista (Code

Smells Solutions) todas las soluciones generadas con sus

respectivas métricas al usuario.

User Interface

views & controls

Es un conjunto de componentes de interfaces de usuario (vistas,

cuadros de dialogo and action handlers) que componen a Bandago.

Estos presentan la interfaz de usuario y a través de ella se provee la

funcionalidad que los desarrolladores van a utilizar. El usuario

puede interactuar con los wizards para realizar las refactorizaciones

encadenadas. Además, se puede visualizar las soluciones

propuestas.

ICompilationUnit Este es el archivo que contiene todo el código Java. Es la manera de

representar y modificar todo el acceso al código fuente de un

proyecto en la plataforma de Eclipse. Es donde se aplica la

refactorización y se mantiene un archivo de estos por cada solución

generada.

Code Smell

Feature Envy

Este archivo contiene la información que genera la herramienta

JSpIRIT. Contiene el código fuente del Code Smell identificado y

más información relevante como el tipo, donde se encuentra y qué

clases están afectadas.

Tabla 4.2: Elementos de la arquitectura de Bandago.

Page 48: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

48

Figura 4.13: Arquitectura de alto nivel de Bandago.

El componente Bandago Refactoring Core es considerado el más importante ya que se

encarga de generar y ejecutar todas los posibles refactorizaciones. También este componente

se encarga de hacer el traspaso de información entre el plugin JSpIRIT y Bandago,

obteniendo así, todos los code smells de un proyecto con sus respectivos rankings. Todas las

decisiones tomadas por el desarrollador, como la elección del Code Smell a refactorizar, son

a través del componente User Interface views & controls que a su vez se comunica con el

Eclipse Runtime.

Page 49: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

49

Capítulo 5: Casos de estudio

5.1 Proyectos evaluados y operatoria de la evaluación

En este capítulo se evalúa el enfoque propuesto respondiendo tres preguntas de investigación:

RQ#1: ¿Qué porcentaje de Feature Envy son automáticamente solucionadas por el

enfoque propuesto, sin necesidad de intervención del desarrollador?

RQ#2: ¿Solucionar las Feature Envy permite solucionar otros Code Smells?

RQ#3: ¿Son complementarias las soluciones identificadas por el enfoque propuesto

y por JDeodorant en la refactorización de Feature Envy?

Para responder las preguntas de investigación (Research Questions) se tomaron 10 proyectos

Java para ser analizados por Bandago, los cuales fueron obtenidos de Qualitas Corpus [44],

una colección de sistemas open source utilizados para fines de investigación. En la tabla 5.1

se listan los proyectos utilizados.

Nombre del sistema Cantidad de clases

Apache-jspf-resolver 140

Fitjava 95

Jmoney 47

Jparse 75

Jpf 139

Junit 1077

MobileMedia 51

Oscache 115

Quickserver 199

Squirrel 73

Total 2011

Tabla 5.1: Proyectos evaluados

Page 50: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

50

Para llevar a cabo los experimentos, se tomaron como entrada las Feature Envy encontradas

por el plugin JSpIRIT [13]. Luego, se ejecutó el enfoque sobre cada una de las entradas

identificadas para su análisis.

Se analizaron individualmente las Feature Envy y se refactorizaron para intentar solucionar

el code smell. Como resultado se obtuvieron los códigos fuente de cada una de las clases

refactorizadas que luego fueron analizados.

Para realizar el análisis de los resultados, fueron tomados los siguientes datos de cada

sistema, obtenidos a partir de la ejecución de la herramienta:

Se creó un listado con los métodos identificados como Feature Envy.

Se generó un archivo que contiene los Code Smells del sistema, tanto para el código

original como para el sistema refactorizado.

Se calcularon las métricas individuales de cada método identificado como Feature

Envy, tanto para el original como para el refactorizado. También se recolectó la

información de la cantidad de soluciones identificadas y de si se introdujeron errores

detectables en tiempo de compilación.

Se generó un log que contiene las métricas de cada Feature Envy resuelta.

Para facilitar el análisis y visualización de los datos se decidió plasmar la información de los

code smells identificados por JSpIRIT en una base de datos, para facilitar la visualización de

la información obtenida. Se crearon dos tablas, una con la información relativa a la cantidad

de code smells de cada sistema analizado antes de refactorizar todas las Feature Envy

posibles, y otra con la misma información post-refactoring. De esta forma fue posible analizar

tanto las Feature Envy solucionadas como el impacto de dichas soluciones sobre los otros

code smells de un sistema.

Se calcularon las métricas asociadas a la existencia de Feature Envy (ATFD, LAA y FDP).

La métrica Access to Foreign Data (ATFD) indica el uso directo de atributos de otras clases.

La métrica Locality of Attribute Accesses (LAA) indica la relación entre el acceso a atributos

locales y el acceso a atributos extranjeros. Finalmente, la métrica Foreign Data Providers

(FDP) indica la cantidad de clases que proveen atributos extranjeros al método. En cuanto a

la obtención de las mismas, debido a que no fue posible encontrar una herramienta de análisis

de métricas que identificara las métricas relacionadas con Feature Envy se analizaron

individualmente al refactorizar cada Feature Envy y se persistieron en la base de datos para

su análisis.

El análisis realizado se lleva a cabo refactorizando cada Feature Envy encontrada en un

sistema. El proceso de refactorización es aplicado automáticamente por el enfoque

implementado.

Como se puede observar en la Figura 5.1, la operatoria del experimento consiste en recibir

como entrada un proyecto Java y para cada Feature Envy encontrada, calcular mediante una

heurística, el conjunto de soluciones posibles. Estas soluciones y sus respectivas métricas se

Page 51: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

51

almacenan en una base de datos para su posterior análisis. Para completar la salida, se obtiene

el conjunto de proyectos refactorizados.

Figura 5.1: Diagrama de la operatoria del experimento

5.2 Características de las Feature Envy

Al avanzar en la recolección de datos, fue posible identificar las características generales de

las Feature Envy identificadas en los sistemas analizados.

En primer lugar, se define el universo de Feature Envy utilizadas para el caso de estudio. En

la Tabla 5.2, se enumeran la cantidad de Feature Envy de cada sistema.

Nombre del sistema Cantidad de Feature Envy

Apache-jspf-resolver 28

Fitjava 31

Jmoney 9

Jparse 50

Jpf 43

Junit 46

Page 52: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

52

MobileMedia 10

Oscache 42

Quickserver 45

Squirrel 41

Tabla 5.2: Cantidad de Feature Envy por proyecto

De esta forma, se puede ver que fueron analizadas un total de 345 Feature Envy para obtener

los datos utilizados en el caso de estudio.

Una vez definido el universo de análisis, fue posible centrarse en características propias de

las Feature Envy identificadas. Como aspecto importante, se pueden observar los valores

promedio de las métricas relacionadas a este code smell obtenidas del análisis de todos los

sistemas.

Figura 5.2: Boxplot para la métrica ATFD

Como se ve en la Figura 5.2, la métrica ATFD tiende a ser muy alta, con una mediana de

5,295 considerando el total de los sistemas analizados. Esto significa que los métodos

identificados utilizan una elevada cantidad de atributos o métodos pertenecientes a otras

clases. A su vez, al poseer valores bajos de la métrica FDP, fue posible identificar clases

candidatas que recibían una gran cantidad de accesos a sus atributos desde el método

identificado como Feature Envy.

Page 53: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

53

Figura 5.3: Boxplot para la métrica LAA

Como se ve en la Figura 5.3, para la segunda métrica, LAA, el valor promedio dio un

resultado inesperadamente bajo, con una mediana de 0,02. Esto significa que la mayoría de

los métodos identificados como Feature Envy no utilizaban ninguna variable de instancia o

método propio, con lo cual toma aún más sentido la necesidad de mover dicho método de

una clase a la cual no pertenece.

Figura 5.4: Boxplot para la métrica FDP

En último lugar, como se puede observar en la Figura 5.4, se identificó el promedio de clases

envidiadas por cada Feature Envy. Como era esperado, el resultado de la mediana fue 1,5.

Adicionalmente, se puede observar que la mayoría de los valores se encuentran contenidos

entre la mediana y el cuartil 1 (q1), con lo cual la tendencia es cercana a 1. Esto se debe a los

bajos valores de la métrica FDP para los métodos, un factor necesario para estar en presencia

de una Feature Envy, el cual reduce el universo de posibles clases envidiadas.

Page 54: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

54

5.3 RQ#1: ¿Qué porcentaje de Feature Envy son automáticamente

solucionadas por el enfoque propuesto, sin necesidad de intervención del

desarrollador?

En esta sección se abordó la RQ#1 con el objetivo de analizar el porcentaje de Feature Envy

que se logran solucionar, diferenciando las soluciones completamente automatizadas de las

que requieren intervenciones adicionales por parte del desarrollador.

5.3.1 Hipótesis

Para analizar el porcentaje de Feature Envy solucionadas se analiza el conjunto de code

smells identificados por JSpIRIT a partir del código original de cada proyecto. Luego se

compara con el conjunto de code smells identificados luego de refactorizar todas las Feature

Envy posibles. Además, se tiene en cuenta si dicha refactorización necesitó la intervención

del desarrollador para dejar el código del método en un estado consistente, sin errores

detectables en tiempo de compilación. La hipótesis es que la herramienta permite solucionar

de los proyectos al menos un 25% de las Feature Envy detectadas por JSpIRIT.

Se establece este número como umbral para la hipótesis presentada por dos motivos:

Al utilizar la API JDT de Eclipse, como se mencionó en el capítulo 3, existirá un

número considerable de métodos que no cumplirán con las condiciones requeridas

para realizar el refactor Move Method.

Debido a que el objetivo del enfoque es la identificación de soluciones y no la

implementación del conjunto de precondiciones y postcondiciones para asegurar la

no introducción de errores luego de la aplicación del refactoring Move Method, un

alto porcentaje de soluciones contiene errores, por lo que requieren intervención del

desarrollador.

Formalizando:

H0: La herramienta soluciona al menos un 25% de las Feature Envy

H1: La herramienta soluciona menos de un 25% de las Feature Envy

Se prueba esta hipótesis comparando el conjunto de Feature Envy que afectan a cada proyecto

antes de ser refactorizado con el conjunto de Feature Envy obtenidas luego de refactorizarlos

con la herramienta. De esta manera se puede encontrar el porcentaje de resolución de Feature

Envy de la herramienta. Conjuntamente se analiza el porcentaje de Feature Envy que se

refactorizaron de forma completamente automática y aquellas que requirieron la intervención

del desarrollador para corregir errores.

5.3.2 Análisis e Interpretación

A partir de comparar los conjuntos de code smells de cada proyecto realizando el cruce de

datos pertinente en la base de datos generada, se realizaron la Tabla 5.3 y la Tabla 5.4.

Analizando la primera tabla se puede concluir que de un total de 345 Feature Envy

detectadas, el 4,06% fueron solucionadas sin la intervención del desarrollador. Analizando

Page 55: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

55

la Tabla 5.4 el porcentaje se eleva considerablemente, concluyendo que de las 345 Feature

Envy el 33,33% fueron solucionadas con la intervención del desarrollador. Esto ocurre

debido a que el enfoque está orientado a resolver el code smell Feature Envy, siendo una

tarea que excede a este trabajo el control de precondiciones para no introducir errores al

realizar un Move Method. El mejor porcentaje de resolución obtenido para un proyecto fue

21,43% automáticamente (apache-jspf-resolver) y 73,17% luego de la corrección de errores

(Squirrel). En cuanto a los peores porcentajes obtenidos, se identificó un 0%

automáticamente para 6 proyectos diferentes y un 4,34% luego de la intervención del

desarrollador para el proyecto junit. El alto número de proyectos con 0% de resolución

automática se debe a que, como se mencionó en el planteo de la hipótesis, el enfoque no está

centrado en identificar el conjunto de precondiciones y postcondiciones previos a la

aplicación del refactoring Move Method. Esto conlleva a que la gran mayoría de las

soluciones identificadas requieran intervención del desarrollador.

Nombre del sistema Cantidad de FE

detectadas

Cantidad de FE

solucionadas

Porcentaje

Apache-jspf-resolver 28 6 21,43%

Fitjava 31 3 9,67%

Jmoney 9 0 0%

Jparse 50 2 4%

Jpf 43 2 4,76%

Junit 46 0 0%

MobileMedia 10 0 0%

Oscache 42 0 0%

Quickserver 45 0 0%

Squirrel 41 1 2,44%

Totales 345 14 4,06%

Tabla 5.3: Resultados de Feature Envy analizadas y resueltas automáticamente

Page 56: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

56

Nombre del sistema Cantidad de FE

detectadas

Cantidad de FE

solucionadas

Porcentaje

Apache-jspf-resolver 28 7 25%

Fitjava 31 14 45,16%

Jmoney 9 4 44,44%

Jparse 50 12 24%

Jpf 43 15 35,71%

Junit 46 2 4,34%

MobileMedia 10 2 20%

Oscache 42 13 30,23%

Quickserver 45 16 35,55%

Squirrel 41 30 73,17%

Totales 345 115 31,30%

Tabla 5.4: Resultados de Feature Envy analizadas y resueltas luego de la intervención por

parte del desarrollador

Realizando un análisis integral de porcentaje de resolución, sin discriminar los resultados de

acuerdo a la intervención del desarrollador, es posible observar en la Tabla 5.5 que de las 345

Feature Envy detectadas, el 37,39% fueron resueltas. El mejor resultado obtenido sigue

siendo 75,61% (Squirrel). En cuanto al peor porcentaje obtenido, se identificó un 4,34% para

el proyecto junit.

Page 57: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

57

Nombre del sistema Cantidad de FE

detectadas

Cantidad de FE

solucionadas

Porcentaje

Apache-jspf-resolver 28 13 46,43%

Fitjava 31 17 54,84%

Jmoney 9 4 44,44%

Jparse 50 14 28%

Jpf 43 17 40,47%

Junit 46 2 4,34%

MobileMedia 10 2 20%

Oscache 42 13 30,23%

Quickserver 45 16 35,55%

Squirrel 41 31 75,61%

Totales 345 129 37,39%

Tabla 5.5: Resultados de Feature Envy analizadas y resueltas

A partir del análisis de las Feature Envy, se detectó un alto porcentaje de métodos en los

cuales fue necesario extraer completamente el mismo y no solo una porción (89,15%),

como se puede ver en la Figura 5.5.

Page 58: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

58

Figura 5.5: Extracción Total vs Extracción Parcial

Esto se debe a dos grandes factores. El más importante es que, cómo se indicó en la sección

5.2 (Características de las Feature Envy), un gran porcentaje de las mismas no posee accesos

a atributos (LAA = 0), por lo cual, de acuerdo a la estrategia del enfoque, se define extraer

completamente el método. En segundo lugar, una gran cantidad de métodos en un sistema

poseen el último acceso a una clase extranjera dentro de un statement indivisible (Por

ejemplo, un FOR) y por lo tanto se debe mover la totalidad del método para no alterar el

comportamiento del sistema.

El otro comportamiento detectado es la identificación de más de una solución. Como se puede

ver en la Figura 5.6, la cantidad de Feature Envy en las cuales se identifica más de una

solución es realmente baja.

Figura 5.6: Cantidad de soluciones identificadas

Page 59: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

59

Para comprender esta relación, es necesario tener en cuenta cómo funciona la API JDT de

Eclipse, la cual fue utilizada para la aplicación del refactoring Move Method. El universo de

clases a las cuales se permite mover un método es limitado. Para que sea posible realizar este

refactoring sobre una clase candidata, es decir, mover el método a dicha clase, es necesario

que los accesos a la clase candidata sean realizados a través de un parámetro del método

catalogado como Feature Envy, o a través de una variable de instancia de la clase original.

Esta limitación genera una baja importante en el universo de soluciones, debido a que, para

poder aplicar una solución, es necesario seleccionar una clase candidata y que a su vez

Eclipse permita la aplicación del refactoring. Esta limitación puede observarse en la Figura

5.7 tomando el ejemplo del método MusicAlbumData.getMusicFromRecordStore del

proyecto MobileMedia.

Figura 5.7: Limitaciones de Eclipse al aplicar el refactoring Move Method

Con los resultados obtenidos se puede concluir que la hipótesis H0 es rechazada ya que el

enfoque, sin introducir errores, soluciona el 4,06% de las Feature Envy detectadas,

aceptándose la hipótesis H1.

5.4 RQ#2: ¿Solucionar las Feature Envy permite solucionar otros code

smells?

En esta sección se analizan los code smells relacionados con las Feature Envy y su efecto

luego de que las Feature Envy fueron refactorizadas.

5.4.1 Hipótesis

Para responder la research question se realiza una comparación entre el listado de code smells

generado por JSpIRIT a partir del código original de cada proyecto con respecto al generado

luego de realizar el refactoring. Dichos listados son persistidos en una tabla de una base de

datos para cada proyecto analizado. Se analizan únicamente los code smells detectados por

JSpIRIT que estén relacionados con la Feature Envy que son God Class, Intensive Coupling,

Shotgun Surgery, Tradition Breaker y Data Class. Formalizando:

Page 60: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

60

H0: El enfoque soluciona code smells relacionados con el refactoring de Feature

Envy.

H1: El enfoque no soluciona code smells relacionados con el refactoring de Feature

Envy.

Se prueba esta hipótesis comparando los listados antes mencionados, analizando los casos

donde los code smells fueron solucionados y donde fueron creados.

5.4.2 Análisis e Interpretación

Como se señaló en la RQ#1, se logró solucionar, en promedio, un 37,99% de las Feature

Envy de los proyectos que fueron refactorizados, sin analizar la intervención del

desarrollador para la corrección de errores introducidos. Este code smell, a su vez, se

encuentra relacionado con otros code smells, teniendo un impacto positivo en algunos casos,

y negativo en otros.

En la Tabla 5.6 se compara la cantidad de smells del sistema Squirrel antes y después de

aplicar la refactorización de Feature Envy. En este caso se puede observar la cantidad de

Feature Envy que había originalmente (41), las solucionadas (23) y las creadas (0).

Code smell Cantidad pre-

refactoring

Cantidad post-

refactoring

Solucionad

os

Creados

Brain Class 1 1 0 0

Brain Method 2 2 0 0

Dispersed Coupling 1 1 0 0

Feature Envy 41 18 23 0

God Class 3 3 0 0

Intensive Coupling 5 4 1 0

Shotgun Surgery 2 2 0 0

Tabla 5.6: Comparación de Code Smells pre y post refactoring

En primer lugar, se analizaron los smells solucionados luego de refactorizar todas las Feature

Envy posibles de un sistema. Como se puede ver en la Figura 5.8, la cantidad de code smells

adicionales afectados positivamente es muy baja. Esto se debe principalmente al bajo

porcentaje de Feature Envy solucionadas para cada sistema. Además, es necesario examinar

las características de cada smell adicional solucionado.

Page 61: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

61

Figura 5.8: Cantidad de smells solucionados por el enfoque

Los smells solucionados al menos una vez fueron God Class, Shotgun Surgery e Intensive

Coupling, como se puede ver en la Figura 5.9.

Para el caso de God Class, se comprende el bajo porcentaje obtenido (3,54% en promedio

para todos los proyectos) debido a que la mayoría de las Feature Envy, como se vio en la

RQ#1, fueron movidas completamente, por lo que, en caso de ser una God Class,

simplemente se movió este code smell a una nueva clase, sin solucionarlo.

En cuanto a Intensive Coupling, el bajo porcentaje (2,70% en promedio para todos los

proyectos) cobra sentido al comprender que es necesario que la Feature Envy refactorizada

sea a su vez una Intensive Coupling y la clase a la que es movida sea la misma que genera

Intensive Coupling. Esto no es común, debido a que el smell Intensive Coupling depende de

que los llamados a métodos proveedores sean múltiples, es decir, a diferentes métodos, y una

Feature Envy simplemente se genera cuando los llamados exceden un umbral (ATFD >

FEW) que no necesariamente está compuesto de múltiples operaciones.

En cuanto a Shotgun Surgery, el bajo porcentaje (3,54% en promedio para todos los

proyectosse comprende al analizar uno de los factores clave para que este smell se produzca.

Esto es, el número de proveedores para que este smell se genere debe ser alto (CC > MANY),

con lo cual es poco probable que un método afectado por Shotgun Surgery sea también

2

1

1

12

13

4

13

16

2

2

10

15

231

-1

1

1

-1

-1

-1

-1

apache-jspf-resolver

fitjava

jmoney

jparse

jpf

junit

MobileMedia

oscache

Quickserver

Squirrel

Cantidad solucionada

Pro

yect

o

Data Class Tradition Breaker God Class Intensive Coupling Feature Envy Shotgun Surgery

Page 62: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

62

considerado Feature Envy. Sin embargo, si se da el caso que la Feature Envy movida genere

una Shotgun Surgery en la clase a la cual fue movida, la Feature Envy movida podría

solucionar una de las clases proveedoras, solucionando también este smell.

Figura 5.9: Porcentajes de smells solucionados

En segundo lugar, se analizaron los smells creados luego de refactorizar todas las Feature

Envy posibles de un sistema. Como se puede ver en la Figura 5.10, la cantidad de code smells

adicionales afectados negativamente también es muy baja. Esto se debe principalmente al

bajo porcentaje de Feature Envy solucionadas para cada sistema. Además, es necesario

examinar las características de cada smell adicional creado.

Figura 5.10: Cantidad de smells creados por el enfoque

3,54%

2,70%

4,35%

0,00% 20,00% 40,00% 60,00% 80,00% 100,00%

Shotgun Surgery

Intensive Coupling

God Class

Porcentaje sobre el total

Co

de

Smel

ls s

olu

cio

nad

os

1

1

1

1

1

apache-jspf-resolver

jparse

junit

Quickserver

Cantidad creada

Pro

yect

o

Data Class Tradition Breaker God Class

Page 63: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

63

Los smells creados al menos una vez fueron Tradition Breaker, Data Class y God Class, como

se puede observar en la Figura 5.11.

Para el caso de God Class, el porcentaje es muy bajo (4,35% en promedio para todos los

proyectos) y para poder comprender cómo se generó este smell, hubo que analizar el caso

encontrado individualmente, debido a que se generó por una situación muy particular de un

sistema (apache-jspf-resolver). Lo que ocurrió, fue que este sistema poseía una gran cantidad

de clases similares con métodos similares. Entre estos métodos se encontraba una Feature

Envy que siempre envidiaba de la misma clase. El resultado fue que la refactorización de

todas las Feature Envy implicaba mover ese método a la misma clase, lo que dio como

resultado la sobrecarga de una única clase con todos los métodos similares que envidiaban

de ella, generando una God Class.

En cuanto a Tradition Breaker, el porcentaje obtenido (14,28% en promedio para todos los

proyectos) se comprenden debido a que al mover una Feature Envy, no se tienen en cuenta

las características del método al cual se mueven. Por ello es que, si la clase candidata elegida

es hija en una jerarquía de herencia, y se especializa excesivamente al recibir el método

movido por el enfoque, es posible generar este smell.

En cuanto a Data Class, también ocurrió la creación de este smell por un caso particular. Se

trataba de una clase muy simple en la cual el único método que añadía complejidad resulto

ser una Feature Envy. Al ser movido, se generó este smell. El porcentaje también fue muy

bajo (2,17% en promedio para todos los proyectos)

Figura 5.11: Porcentajes de smells creados

Finalmente, para comprender el análisis total de los resultados obtenidos, se puede ver en la

Figura 5.12 el total de code smells afectados por la refactorización de Feature Envy.

14,28%

2,17%

4,35%

0,00% 20,00% 40,00% 60,00% 80,00% 100,00%

Tradition Breaker

Data Class

God Class

Porcentaje sobre el total

Co

de

Smel

ls c

read

os

Page 64: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

64

Figura 5.12: Code Smells afectados por el enfoque

Este análisis permite concluir que el enfoque no posee un alto impacto en la solución de otros

code smells como consecuencia de la solución de Feature Envy aceptándose así la hipótesis

H1. Los resultados confirman la solución de un 3,53% de los code smells relacionados con

Feature Envy, el cual es considerado muy bajo para ser considerado relevante. Por otro lado,

también se confirma que no se generaron impactos negativos (code smells creados)

significativos.

5.5 RQ#3: ¿Son complementarias las soluciones identificadas por el

enfoque propuesto y por JDeodorant en la refactorización de Feature

Envy?

En esta sección se analizarán las Feature Envy resueltas por JDeodorant y por el enfoque

propuesto con el objetivo de comparar ambas herramientas.

5.5.1 Hipótesis

El objetivo de esta evaluación es comparar el enfoque propuesto con la herramienta

JDeodorant. Para responder esta pregunta se analizarán los resultados teniendo en cuenta dos

universos diferentes de soluciones:

Las Feature Envy identificadas por ambas herramientas simultáneamente.

Page 65: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

65

Cantidad total de Feature Envy identificadas, independientemente de si fueron

detectadas por una o ambas herramientas.

Nuestra hipótesis es que ambas herramientas son complementarias, aumentando

significativamente el universo de Feature Envy refactorizadas en un proyecto al usarse

simultáneamente.

Formalizando:

H0: Los enfoques utilizados simultáneamente mejoran significativamente el

porcentaje de resolución de Feature Envy de un sistema.

H1: Los enfoques utilizados simultáneamente no mejoran significativamente el

porcentaje de resolución de Feature Envy de un sistema.

Se probará esta hipótesis comparando los universos antes mencionados, analizando las

resoluciones identificadas por ambas herramientas.

5.5.2 Análisis e Interpretación

En primer lugar, como se indicó anteriormente, se tomó el conjunto de Feature Envy

identificadas por ambas herramientas. Se utilizaron los 10 proyectos presentados

inicialmente en el caso de estudio. Es importante aclarar que JDeodorant únicamente

identifica aquellas Feature Envy sobre las cuales encuentra una solución. En cambio,

JSpIRIT (herramienta sobre la cual se implementó el enfoque propuesto) genera el listado

completo de Feature Envy de un proyecto, y luego se le aplica el enfoque para definir si existe

solución. Por lo tanto, la intersección de Feature Envy identificadas resulta en un conjunto

de métodos mucho más reducido, debido a que JDeodorant identifica una cantidad mucho

menor de Feature Envy que JSpIRIT, como se ve en la Figura 5.13.

Figura 5.13: Cantidad de Feature Envy identificadas por JDeodorant y JSpIRIT

Sin embargo, el universo obtenido resulta en un conjunto de métodos sobre los cuales

JDeodorant tiene un 100% de efectividad a la hora de identificar un refactoring para la

Page 66: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

66

solución del code smell. De todas formas, como se ve en la Figura 5.14, el enfoque propuesto

consiguió obtener una solución en el 90% de los casos.

Figura 5.14: Porcentaje de resolución de ambas herramientas sobre la intersección

El foco principal en el desarrollo de la herramienta JDeodorant en cuanto a refactorización

de Feature Envy fue la implementación del máximo número de controles de precondiciones

y postcondiciones necesarias para la aplicación del refactoring Move Method sin introducir

errores detectables en tiempo de compilación ni cambios en el comportamiento de un sistema.

En este aspecto, al analizar los métodos resueltos, se puede detectar una importante mejora

en la calidad de las soluciones planteadas por JDeodorant, debido a que el enfoque propuesto

utiliza la API JDT de Eclipse y no implementa particularmente el extenso conjunto de

condiciones necesarias para evitar la introducción de errores.

Finalmente, para profundizar el análisis, se revisó el método resuelto por JDeodorant que no

pudo ser resuelto por JSpIRIT, para comprender cuál es la causa de que el enfoque propuesto

no pudiera identificar una solución.

Figura 5.15: Método solucionado por JDeodorant y no solucionado por el enfoque

propuesto

Page 67: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

67

El método es MaxCore.buildRunner del proyecto Junit. Al analizar la naturaleza del método,

se puede observar el alto número de sentencias return que posee. El enfoque propuesto, al

intentar realizar una aproximación heurística para definir una estrategia que implique extraer

una porción y no su totalidad, selecciona la extracción parcial del método, desde la primer

ocurrencia del uso de la clase extranjera hasta la última, como se ve en la Figura 5.15. Sin

embargo, al intentar hacer esta extracción, los controles de la API JDT para el refactoring

Extract Method impiden la operación, debido a que ésta alteraría el normal comportamiento

del método al extraer algunas sentencias return y otras no. JDeodorant no presenta esta

complicación porque siempre mueve completamente el método seleccionado.

Posteriormente, se analizó el universo completo de Feature Envy, formado por la unión de

Feature Envy identificadas, es decir, aquellas identificadas por JDeodorant, por JSpIRIT o

por ambas. Como se pudo ver en la Figura 5.13, JDeodorant identifica 47 Feature Envy,

mientras que JSpIRIT identifica 345 Feature Envy. De esta forma, teniendo en cuenta que 10

Feature Envy son identificadas por ambas herramientas, el universo total de Feature Envy

identificadas es de 382. Como JDeodorant identifica las Feature Envy que resuelve, esta

herramienta resuelve 47 Feature Envy. Por su parte, el enfoque propuesto no resuelve la

totalidad de Feature Envy identificadas por JSpIRIT, dando un total de 129, como se ve en

la Figura 5.16.

Figura 5.16: Cantidad de Feature Envy resueltas por ambas herramientas

Finalmente, se puede observar en la Figura 5.17 el porcentaje de resolución de Feature Envy

de cada herramienta sobre el universo total considerado. JDeodorant resuelve un 12,30% del

total de Feature Envy, mientras que JSpIRIT alcanza un porcentaje de resolución de 33,77%

129

47

0 20 40 60 80 100 120 140

JSpIRIT

Jdeodorant

Canitdad total de Feature Envy resueltas

Her

ram

ien

ta

Page 68: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

68

Figura 5.17: Porcentaje de Feature Envy resueltas por ambas herramientas

Teniendo en cuenta que 9 Feature Envy son resueltas por ambas herramientas como se vio

en el análisis previo de la intersección, entre ambas herramientas se resuelven 167 Feature

Envy, lo cual corresponde a un porcentaje total de resolución de 43,72%.

Éste análisis permite concluir que ambas herramientas son complementarias a la hora de

lograr mejores resultados en la resolución de Feature Envy de un sistema, cumpliéndose así

la hipótesis H0. Los resultados confirman que la intersección de ambos universos de

resoluciones es pequeña en comparación al universo total, y que ambas herramientas

resuelven diferentes Feature Envy por su estrategia de identificación, por lo que el porcentaje

de resolución total se ve significativamente mejorado al aplicar ambas herramientas

simultáneamente.

Page 69: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

69

Capítulo 6: Conclusión

6.1 Conclusiones finales

Los code smells son síntomas útiles para la identificación de problemas estructurales de un

sistema que se relacionan con problemas de modificabilidad. Surgen por la utilización de

“malas prácticas” al desarrollar un sistema. Los CS son decisiones pobres de implementación

que hacen que un sistema orientado a objetos sea difícil de mantener [35]. Son las

descripciones generales de código problemático y sirven para ayudar a los desarrolladores a

decidir cuándo un código necesita refactorización [36], es decir, su detección permite

identificar oportunidades de refactorización de código para la mejora de su calidad. Una vez

aplicado el refactoring apropiado, en la mayoría de los casos se mejoran diversos aspectos de

calidad como mantenibilidad, comprensibilidad y reusabilidad. [37]. Feature Envy puede ser

considerado el síntoma más común relacionado con problemas de acoplamiento y cohesión

[38]. Es un método que parece más interesado en los datos de otra clase que en los de su

propia clase [3]. Este problema puede ser solucionado aplicando el refactoring Move Method

únicamente, o aplicando Extract Method y Move Method en conjunto. Existen herramientas

para la recomendación y aplicación de Move Method para la solución de este code smell. Sin

embargo, ninguna se encarga de proponer la posibilidad de aplicación del refactoring Extract

Method previo al Move Method, ya que requiere realizar un análisis más detallado del

código.

En este trabajo se abordaro el problema de identificación de oportunidades de refactoring de

Feature Envy y su aplicación mediante la presentación de un enfoque realizado sobre la

extensión Bandago del plugin JSpIRIT [13], brindándole al desarrollador más de una

solución en caso de ser posible, y analizando oportunidades de realizar una extracción de

código del método previo a ser movido a otra clase. El enfoque se basa en un algoritmo

heurístico para la identificación de posibilidades de aplicación de Extract Method, y cada

solución propuesta es presentada al desarrollador acompañada con las métricas relacionadas

con el code smell Feature Envy. El enfoque fue implementado en el lenguaje Java.

Para poder validar los beneficios del enfoque se realizó un caso de estudio con tres research

questions. Estas research question corroboraron la efectividad del enfoque, permitiendo

además analizar varios aspectos del mismo. En la primer research question, se analizaron

todas las Feature Envy que se lograron solucionar automáticamente. Si bien el porcentaje

promedio resultó ser bajo, se corroboró que al considerar las soluciones que requerían

intervención por parte del desarrollador, se obtiene un porcentaje completamente aceptable

cuando se necesita identificar soluciones para un smell complejo como lo es Feature Envy.

En la segunda research se analizó si la solución de Feature Envy permite solucionar otros

code smells detectados por JSpIRIT. En este caso, se rechazó la hipótesis inicial al comprobar

que la solución de Feature Envy tenía una baja incidencia sobre los demás code smells de

todo un sistema. Para la tercera research question se comparó el enfoque propuesto con

JDeodorant, la única herramienta que propone un enfoque de recomendación y resolución de

Feature Envy. Se comprobó que el enfoque detecta una mayor cantidad de soluciones y que

Page 70: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

70

ambas herramientas pueden ser utilizadas complementariamente para la resolución de un

conjunto de Feature Envy significativamente mayor.

6.2 Contribuciones

La contribución más importante de este trabajo es asistir al desarrollador al refactorizar las

Feature Envy de un sistema, analizando posibilidades de extracción y de múltiples

soluciones. Específicamente, se pueden resaltar las siguientes contribuciones:

Automatización del proceso de refactorización: Si bien es cierto que el proceso

requiere la intervención del desarrollador para la corrección de errores, se automatiza

el análisis y aplicación de los refactorings Extract Method y Move Method. Se

corroboró que a excepción de JDeodorant, las otras herramientas existentes se limitan

a la recomendación de refactorizaciones.

Múltiples soluciones: El enfoque le brinda al desarrollador varias soluciones en caso

de existir, acompañadas por sus métricas. Esto permite al desarrollador hacer un

análisis de las métricas para decidir qué solución desea aplicar.

Posibilidades de aplicación de Extract Method previo al Move Method: El enfoque

analiza la posibilidad de extraer una parte del método para no mover código

innecesario a otra clase. De esta forma, solo se mueve la porción de código que

realmente está generando el code smell.

Rápido tiempo de respuesta: Al estar basado en un enfoque heurístico, la herramienta

genera soluciones en pocos segundos.

Información detallada: Todas las soluciones generadas muestran información

adicional para la toma de decisiones del desarrollador. Se presenta el conjunto de

métricas relacionadas con Feature Envy para cada solución.

Extensibilidad: Se brinda la posibilidad de agregar nuevas heurísticas para la

detección de refactorizaciones posibles respetando una interfaz común.

6.3 Limitaciones

Si bien la herramienta ayuda a resolver las Feature Envy de un sistema, se hallaron algunas

limitaciones:

Introducción de errores: Move Method es un refactor sensible que requiere el control

de un gran conjunto de pre-condiciones y post-condiciones para evitar la introducción

de errores al ser ejecutado. Actualmente no existe soporte para dichas condiciones, y

este trabajo no se enfocó en el control de los mismos. Por este motivo, el esquema

general de la solución es dependiente de la intervención del desarrollador para el

control y corrección de los mismos.

Sólo Java: El enfoque fue desarrollado sobre un plugin para el IDE Eclipse que sólo

trabaja con el lenguaje Java. Aun así, como Java es uno de los lenguajes más

utilizados, no resulta una gran limitación.

Page 71: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

71

Universo de clases candidatas: El universo de clases candidatas identificadas por la

herramienta se ve limitado por la posibilidad de realizar el refactor Move Method a

dicha clase, debido a que actualmente únicamente se permite la aplicación de dicho

refactor sobre clases pertenecientes a parámetros del método o a variables de instancia

de la clase. El enfoque no intenta extender este universo de soluciones.

6.4 Trabajos futuros

Desde el enfoque presentado en esta tesis, y los resultados obtenidos, se identifican varias

líneas de investigación futuras.

En primer lugar, como punto más importante, se puede analizar e incluir el control del

conjunto de pre-condiciones y post-condiciones para la aplicación del refactoring Move

Method sin introducir errores en el código. La herramienta JDeodorant es la más avanzada

en este aspecto, pero incluso dicha herramienta puede llegar a introducir errores detectables

en tiempo de compilación. Esto se debe a la gran cantidad de problemas que pueden

presentarse cuando se mueve un método o fragmento de un método desde su clase original a

una nueva clase.

Otro aspecto que podría mejorarse es la vista previa de la refactorización. Podría agregarse

un análisis más detallado de la solución generada y la clase candidata a la cual se decidió

mover el método. Para poder realizar un mejor análisis de las soluciones, debería extenderse

la actual vista y crearse reportes más detallados de las métricas y los refactors aplicados.

Por último, la investigación podría continuar en torno dos grandes aspectos. En primer lugar

se deberían analizar la aplicación de nuevas heurísticas para identificar una mayor cantidad

de posibilidades de extracción previa al Move Method, debido a que la heurística actual

identifica un porcentaje bajo sobre el total de soluciones. Finalmente, se podríacontinuar con

la eliminación de otros code smells, debido a que es posible que varias técnicas utilizadas en

el enfoque para eliminar Feature Envy pueden ser reutilizadas para eliminar otros code

smells.

Page 72: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

72

Bibliografía

[1] Steidl, Daniela, and Sebastian Eder. "Prioritizing maintainability defects based on

refactoring recommendations." Proceedings of the 22nd International Conference on

Program Comprehension. ACM, 2014.

[2] Fowler, Martin. “Refactoring: improving the design of existing code”. Pearson Education

India, 2002.

[3] Lanza, Michele, and Radu Marinescu. Object-oriented metrics in practice: using software

metrics to characterize, evaluate, and improve the design of object-oriented systems.

Springer Science & Business Media, 2007.

[4] Ettinger, Ran. Refactoring via program slicing and sliding. Diss. University of Oxford,

2006.

[5] Harman, Mark, and Robert Hierons. "An overview of program slicing." Software Focus

2.3 (2001): 85-92.

[6] Komondoor, Raghavan, and Susan Horwitz. "Effective, automatic procedure extraction."

Program Comprehension, 2003. 11th IEEE International Workshop on. IEEE, 2003.

[7] Lakhotia, Arun, and Jean-Christophe Deprez. "Restructuring programs by tucking

statements into functions." Information and Software Technology 40.11 (1998): 677-689.

[8] Weiser, Mark. "Program slicing." Proceedings of the 5th international conference on

Software engineering. IEEE Press, 1981.

[9] De Lucia, Andrea, et al. "Unions of slices are not slices." Software Maintenance and

Reengineering, 2003. Proceedings. Seventh European Conference on. IEEE, 2003.

[10] Pattanaik S., Praksh Boy S., Mohanty R. “Simulated Annealing based placement

algorithms and research challenges: A survey”. Journal of Global Research in Computer

Science Volume 3, No 6, 2012 35-36.

[11] Tsantalis, Nikolaos, and Alexander Chatzigeorgiou. "Identification of extract method

refactoring opportunities for the decomposition of methods." Journal of Systems and

Software 84.10 (2011): 1757-1782.

[12] International Organization for Standardization. ISO 8402: 1994: Quality Management

and Quality Assurance-Vocabulary. International Organization for Standardization, 1994.

[13] Vidal, Santiago A., Claudia Marcos, and J. Andrés Díaz-Pace. "An approach to

prioritize code smells for refactoring." Automated Software Engineering (2014): 1-32.

[14] Nazin H. Madhavji, Juan C. Fernandez-Ramil, Dewayne E. Perry. "Software Evolution

and Feedback" John Wiley & Sons, Ltd. (2006).

[15] Petito, Michael. "Eclipse refactoring." http://people. clarkson. edu/~

dhou/courses/EE564-s07/Eclipse-Refactoring. Pdf 5 (2007): 2010.

[16] Belady, Laszlo A., and Meir M. Lehman. "A model of large program development."

IBM Systems journal 15.3 (1976): 225-252.

[17] Murphy-Hill, Emerson, and Andrew P. Black. "Breaking the barriers to successful

refactoring." Software Engineering, 2008. ICSE'08. ACM/IEEE 30th International

Conference on. IEEE, 2008.

[18] Beck, Kent. Extreme programming explained: embrace change. Addison-Wesley

Professional, 2000.

[19] Kim M., Zimmermann T., Nagappan N. "A Field Study of Refactoring Challenges and

Benefits." Microsoft Research, Redmond., 2012.

Page 73: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

73

[20] Berra, Iñaki and Zuliani Held, Santiago. "Refactorización Automatizada para la

Eliminación de Brain Methods" Tesis de grado. Facultad de Ciencias Exactas, UNICEN

(2015).

[21] Murphy-Hill, Emerson, Chris Parnin, and Andrew P. Black. "How we refactor, and how

we know it." Software Engineering, IEEE Transactions on 38.1 (2012): 5-18.

[22] Ben-Menachem, Mordechai, and G. S. Marliss. Software Quality: Producing Practical,

Consistent Software, Slaying the Software Dragon Series. Boston, MA: International

Thomson Computer Press, 1997.

[23] Garcia, Rubio, and Mario Piattini. "Calidad en el desarrollo y mantenimiento del

software." RA-MA (2003).

[24] C. SenthilMurugan and S.Prakasam Ph.D. "A literal Review of Software Quality

Assurance." International Journal of Computer Applications Volume 78. No.8 (2013).

[25] Fokaefs, M. and Tsantalis, N. “JDeodorant: Identification and Removal of Feature Envy

Bad Smells” Department of Applied Informatics, University of Macedonia. (2007)

[26] Anqueril, N., Oliveira, K., de Sousa K., Batista Dias M. “Software Maintenance seen

as knowledge management issue”. Catholic University of Brasilia, 2006. [27] M.M. Lehman and J.F. Ramil. An approach to a theory of software evolution. In Proceedings

of the 4th international Workshop on Principles of Software Evolution (IWPSE '01), pages 7074,

Vienna, Austria. ACM, 2001.

[28] T.M. Pigoski, “Practical Software Maintenance: Best Practices for Software Investment”, John

Wiley & Sons, Inc., 1996.

[29] Černý, Vladimír. "Thermodynamical approach to the traveling salesman problem: An efficient

simulation algorithm." Journal of optimization theory and applications 45.1 (1985): 4151.

[30] Opdyke, W. “Refactoring object-oriented frameworks” Universitu of Wisconsin – Madison,

1982.

[31]Bomarius, F. Oivo, M. Jaring, P. and Abrahamson P. “Product-Focused Software Process

Improvement” 10th International Conference, PROFES 2009, 2009.

[32] Yamashita, A. “Code Smells as system-level indicators of maintainability: An empirical study”.

The Journal of Systems and Software, Elsevier, 2013.

[33] Wanberg, R. D., “A literature Review on Code Smells and Refactoring”, University of Oslo,

Department of informatics, 2010.

[34] A. O’connor, M. Shonle and W.Griswold. “Star diagram with automated refactorings for

Eclipse” In Proceedings of the 2005 OOPSLA Workshop on Eclipse Tecnology Exchange, pages 16-

20, San Diego, California ACM, 2005.

[35] Khomn F., Di Penta M. and Guéhéneuc Y. “An Exploratory Study of the Impact of Code Smells

on Software Change-proneness” École Polytechnique de Montréal, Canada. University of

Sannio,Benevento, Italy, 2009.

[36] Mäntylä M. V., Lasseniuss C., “Subjective evaluation of software evolvability using code smells:

An empirical study”. Springer Science + Business Media, LLC 2006.

[37] Chatzigeorgiou, A., Manakos A. “Investigating the Evolution of Bad Smells in Object-Oriented

Code” Department of Applied Informatics, University of Macedonia, 2010.

[38] Oliveto, R., Bavota G., Gethers M., Poshyvanyk D., De Lucia A. “Identifying Method Friendship

to Remove The Feature Envy Bad Smell (NIER Track)”. University of Molise, Pesche, Italy.

University of Salerno, Fisciano, Italy. The College of William and Mary, USA. 2011.

[39] Weiser, M. “Program Slicing”. IEEE Transactions on Software Engineering. Vol – SE-10. 1984.

[40] Bavota G., Oliveto R., Gethers M., Poshyvanyk D., De Lucia A. “MethodBook: Recommending

Move Method Refactorings via Rational Topic Models” IEEE Transactions on Software Engineering,

2014.

Page 74: REFACTORIZACIÓN AUTOMATIZADA PARA LA ELIMINACIÓN DE

74

[41] Ali O., Marouane K., Mel O., Houari S., Kalyanmoy D., Katsuro I., “MORE: A Multi-Objective

Refactoring Recommendation Approach to Introducing Design Patterns and Fixing Code Smells”.

Journal of Software: Evolution and Process. 2017.

[42] Ali, O., Katsuro I., Takashi I., Naoya U. “c-JRefRec: Change-Based Identification of Move

Method Refactoring Opportunities”. Department of Computer Science and Software Engineering,

CIT, UAE University, 2016.

[42] Sales V., Terra R., Miranda L. F., Valente M., “JMove: Seus Métodos em Classes Apropiadas”.

Departamento de Ciencia da Computaçao, Universidade General de Minas Gerais, 2013.

[43] P. Clements, F. Bachmann, L. Bass, D. Garlan, J. Ivers, R. Little, R. Nord and J. Stafford.

“Documenting Software Architectures – Views and Beyond”. AddisonWesley, 2003.

[44] Qualitas web page: http://qualitascorpus.com