método de refactorización de marcos de aplicaciones ...20man… · refactorización de marcos de...

173
S.E.P. S .E.I .T. D.G.I.T. Centro Nacional de Investigación y Desarrollo Tecnológico - Sistema Nacional de Insllutos Tecnobgicos PUBLICA Oireccihn General de Insüiuios Tecnoldgicos Método de Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Inteifaces TESIS Que para Obtener el Grado de: MAESTRO EN CIENCIAS EN CIENCIAS DE LA COMPUTACIÓN Presenta: Manuel Alejandro Valdés Marrero Director de Tesis: Dr. René Santaolaya Salgado Codirector de Tesis: M.C. Ohia Graciela Fragoso Díaz Cuernavaca, lorelos Noviembre del 004

Upload: others

Post on 05-Aug-2020

5 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

S.E.P. S .E.I .T. D.G.I.T.

Centro Nacional de Investigación y Desarrollo Tecnológico -

Sistema Nacional de Insllutos Tecnobgicos

PUBLICA Oireccihn General de Insüiuios Tecnoldgicos

Método de Refactorización de Marcos de Aplicaciones Orientados a Objetos por la

Separación de Inteifaces

TESIS

Que para Obtener el Grado de: MAESTRO EN CIENCIAS EN

CIENCIAS DE LA COMPUTACIÓN

Presenta:

Manuel Alejandro Valdés Marrero

Director de Tesis: Dr. René Santaolaya Salgado

Codirector de Tesis: M.C. O h i a Graciela Fragoso Díaz

Cuernavaca, lorelos Noviembre del 004

Page 2: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato
Page 3: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

S.E.P. S.E.I.T. D .G. I .T.

Centro Nacional de Investigación y Desarrollo Tecnológico -

Sistema Nacional de Institutos Tecnologicos

::I~EP cenídet 3 r r r $L$kj)ej) (r' Dirección General de Institutos Tecnologicor

Método de Refactorización de Marcos de Aplicaciones Orientados a Objetos por la

Separación de Interfaces

TESIS

Que para Obtener el Grado de: MAESTRO EN CIENCIAS EN

CIENCIAS DE LA COMPUTACIÓN

Presenta:

Manuel Alejandro Valdes Marrero

Director de Tesis: Dr. René Santaolaya Salgado

Codirector de Tesis: M.C. O h i a Graciela Fragoso Díaz

Cuernavaca, Morelos Noviembre del 2004 . Esta tesis es parte del proyecto No. 32042-A "Sistema de Administración de Componentes de

Software Basado en Frameworks" financiado por CONACYT, y el proyecto No. 450.01-P "SR2: Sistema de Reingenieria para Reuso" financiado por COSNET.

*

Page 4: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

c

Page 5: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Centro Nacional de Investigación cenide f y o ~ ~ ~ ~ ~ I ~ Tecnológico Sistema Nacional de Institutos Tecnologicos

M10 ACEPTACIÓN DEL DOCUMENTO DE TESIS

Cuemavaca, Mor., a 14 de Octubre del 2004

Dr. Gerardo Reyes Salgado Jefe del Departamento de Ciencias de la Computación Presente.

At'n Dr. René Santaolaya Salgado Presidente de la Academia de Ciencias de la Computación

Nos es grato comunicarle, que conforme a los lineamientos para la obtención del grado de Maestro en Ciencias de este Centro, y después de haber sometido a revisión académica la tesis titulada: Método de Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, realizada por el C. Manuel Alejandro Valdés Marrero, y dirigida por el Dr. René Santaolaya Salgado y la M.C. Oüvia Graciela Fragoso Dim, y habiendo realizado las correcciones que le fueron indicadas, acordamos ACEPTAR el documento final de tesis, así mismo le solicitamos tenga a bien extender el correspondiente oficio de autorización de impresión.

Atentamente La Comisión de Revisión de Tesis

'. I

Revisor

C.C.P. Subdirección Académica Dcpartainento de Servicios Escolares Dircctorcs de tesis Estudiante

Page 6: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato
Page 7: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Centro Nacional de lnvestigacidn ceniúet y Desarrollo Tecnológico Sistema Nacional de Institutos Tecnol6gicos

MI 1 AUTORIZACI~N DE IMPRESI~N DE TESIS

Cuemavaca, Mor., a 27 de Octubre del 2004

C. Manuel Alejandro Valdés Marrero Candidato al grado de Maestro en Ciencias en Ciencias de la Computación Presente.

Después de haber atendido .las indicaciones sugeridas por la Comisión Revisora de la Academia de Ciencias de la Computación en relación a su trabajo de tesis cuyo titulo es: Método de Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato comunicarle que conforme a los lineamientos establecidos para la obtención del grado de Maestro en Ciencias en este centro se le concede la autorización para que proceda con la impresión de su tesis.

Atentam- I

Jefe del Departamento de Ciencias de la Computación

C.C.P. Subdirección Académica Presidente de la Acadcmia de Ciencias de la Computación Dcpartamento de Servicios Escolares Expediente

Page 8: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato
Page 9: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

3 mi h n i t a Nónua Por mostranne que si se quiere, se puede; eres mi motivaciónpara cumpfir esta meta.

Donde quiera que estés, te amo y te e@raiio.

mi quni<lo pdn, %íanueCVa[iies G'&z

Por dame siempre tu amor, apoyoy todo tu tiempo. Eres li, más importante para mt; te quiero mucfio.

Page 10: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato
Page 11: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

JlCOs%ETy a h SE% por 6n&rme su apoyo económico como 6ecari0, ya que sin su ayuda no hu6iera sido posi6h h terminación de esta tesis de %aestría.

Al Centro Nacional de Investigación y DesarronO lecnologico CENIDET, y a todo elpersonacque h60ra en esta institución, por permitirme por un tiempo representary

formarpane dé este centro dé investigación. mi director de tesis, DK Q n é Santaohya Sabado y mi codirectora de tesis, M.C.

Ocivia CracieCa Fragoso (Dúlz, por compartir conmigo sus everiencias, consejos y conocimientos. Xunca oCdaré nuestras pláticas y vizjes, gracias por enseñarme h importancia de h investigación y permitirme ver qué hay más a& delcliarco.

PCcomité reuisor 0% %íhjmo Lápez sánctíez, DE José Luis L i e n car& y aC Dr @aérmo ~@áíuez Ortiz, por su vahsa díosición en h reyinón de este tra6ajo de tesis, y por sus comentarios y sugerencias que contri6uyeron a mejorarlo.

en h revisión de t o a h mis pu6Cuacwnes y por estar siempre &&puesto a dar consejos y sugerencias de forma desinteresh. Sin su ayuda no hu6iera sido posi6li: pu6Ciar 10 que sepu6Cuó.

J mis amigas Leonor y síieih, ustedés hicieron que mi estancia en mmml -fuera muy especial; Las quiero con toa2 eCcorazón, Ias h a r é siempre en é ly en mi mente.

,Z mis compañeros y amigos de computación, en estricto orden afa6étuo:

J C maestro Luis Vds, por su v a h s a

PCicia Pqé&a, por ser U M amiga inconduwnal; Gracias por todos tus consejos y compañía en mis momentos de sufrimiento, te estimo mucho. Priadna J d t h , por ser mi mejor amiga. Disfruté mucho nuestras pláticas y s a L i i , e@ra%ré 10s dúls de paga porque ya no podré estar contigo. Gracias por oírme. Leonorpdriana, mi súper amiga, confidente y psicóbga. En verdadgracias por todo, s@ue como eres, es Io que te hace tan especial; X o regrets, no remorse; 6e gratefucandhappy. Nariana, por ser una compañera muy especial: En eCpoco tiempo que nos tratamos me ayudaste mucho, gracias por darme elvalor que necesitatía con mi ay ay ay! Wufiia, mi compañenta. Lástima que h cosas aca6aron como aca6aron. Gracias por ayudarme a demostrarlé alDr. Pazos que 1a Virgen María síeqste.

@sano, por ser mi confidente. Créeme que &@té mucho nuestras phiticas y actualuaciones. ?€e tornado mucho en cuenta Io que me aconsejaste y Io seguiré iínciendo. Sheih Lu6etfi, que más te puedo decir, ya te Io he dicho todo. Gracias por ser como eres; menina, te deseo toda 1a feltcuíadque haya en este mundo. Yresumido en tres pahtíras.. .

Page 12: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

viamy GuadaCupe, por ser tan 6uena amiga. 3íiiiste 6ien en a6rime h s ojos cuando h i6a a regar, siempre iñ recordaré. Eres una niña muy tierna y mereces ser muy fe l í , ánimo. Xochitl; mi petite, mi ragazza, mi amiga. He aprenáído muchas cosas dé ti, discúCpame por todo pero y a me conoces, eres dé Ias pocas personas que se tomaron lá moléstia de hacerh. Aléjandro, por ser un am@o muy divertido y socia6h. De6enás apreciar más h que te pone enfjente lá d a , no désaproveches esta opoltunlciád:

Francisco, mi 6uen amigo, Siemprefd Gracias por todo 10 que compartimos, por sa6erme escuchary aconsejal: Que seas muy fe& a donde quiera que vayas con

Fre4, por ser tan 6uen compaiíero. D+té mucho nuestras platuas dé programación y dé paseos. Y a altviánate, I tnqno 10 es todo en h d a , M& más es h mejo,: Isaac Moisés, mi tirother, que te puedo decir. (D2sfñlte muchísimo to& nuestras aventuras, en este país y en otros, grazie por todo. & c h h to& Guganas, por c y S. i s a h , por ser un gran amigo, e l más divertido dé todos. Tus íéyendas perdurarán por siempre, ya pórtate 6ien. l e e n d w y te deseo li, mejor, cu& 6ien alpequeño e Isidro, por ser un cuate tan sincero. siempre d i t é dé tu compañh y amistad; esas pGítuas de estadé tirando a todos no Ias cam6iopor ma%. kchléganas en todo. Juan José, por ser tan 6uen compañero y amigo. Gracias porque sin tus moHes, tu ayuh y apoyo no hu6iera sido posi6i. cotlocer a UM persona tan espeaidpara mi Jorge, por h 6 e r compartido tantos momentos. Gracias por to&, Gu i a h a l 6 i h 5 Ias pGtuas, todo. Sé muy feliz con tu familk , por eaós has t o h li, que puedas. José Cuiaérmo, por ser un 6uen compañero y cantante. (DDlsfiuté mucho h reuniones en tu casa, gracias por tu hospitafdady amistad Lub Este6an, por ser mi cy6er camarada. @lbfité mucho Ias platuas, Ias comidas y to& Gu críticas que hchmos . q e r o que se h a n todos tus plánes y ya sahamos dé ese cCu6. Pa6b !@dio, por ser mi casi compadre. Gracias por toda tu ayuda y amistadque me 6rindaste cuando üégué a cuernavaca, lá ciudaddé Ios eternos 6arrancos. Q6er t0 , mi compañero dé aventuras inoCda6lés. Gracias por ser tan 6uen amigo y acompañame a investgar eltirote debv im ese. Di$uta lá vida con tu N.

Q6erto carhs, por ser un cuate muy abvianado y sincero. Gracias por Cas b h a h y traziiás, por todas h platicas y sesiones dé unreal; pero so6re todo por tu amistad:

06ngad0, Grazie, Merci, 6eáank a todos

Page 13: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Resumen

La programación orientada a objetos es uno de los paradigmas actuales que sirven para producir software de calidad, siempre y cuando se respeten y cumplan los principios del diseño orientado a objetos. Uno de estos principios es la Separación de Interfaces, el cual dice que los clientes de cualquier software no deben ser forzados a depender de interfaces que no ocupan.

Un marco de aplicaciones orientado a objetos es un conjunto de clases que trabajan juntas para ofrecer soluciones a muchos problemas específicos u ofrecer servicios dentro del mismo dominio de aplicaciones. Los marcos deben ofrecer métodos para extender SU

funcionalidad y dar facilidades para reusar de manera independiente partes del marco. Si un marco de aplicaciones orientado a objetos cumple los principios orientados a

objetos, puede ser reusado y extendido sin ningún problema. Si se logra el reuso de código, se reduce el tiempo de programación de una nueva aplicación, y también se reduce la posibilidad de defectos, ya que se está usando código previamente probado.

Cuando los marcos no están bien diseñados no se cuenta con estas caractensticas, por lo que es necesario obtenerlas mejorando la arquitectura del marco. Para cambiar la arquitectura se utiliza la refactonzación, que consiste en modificar la arquitectura del marco sin afectar a la funcionalidad del mismo.

Una situación que frecuentemente surge del diseño de un marco es el problema de dependencia de interfaces producido por la herencia de interfaz.cuando las subclases en realidad no ocupan dichas interfaces.

Cuando un marco ;de aplicaciones orientado a objetos tiene el problema de dependencia de interfaces su funcionalidad no puede ser reusada de manera separada, y tampoco puede ser extendida sin violar otros principios orientados a objetos, como el principio de abierto / cerrado.

Para resolver este problema se propone un método de refactorización denominado Separación de Interfaces, cuyo algoritmo fue implementado satisfactoriamente en una herramienta que hace refactorización de manera automática.

Aunque se sabe que este problema existe, no se tiene una forma para medir hasta que grado este problema afecta a los marcos. En esta tesis se propone una métrica orientada a objetos que mida el grado de dependencia debido a interfaces que no se ocupan.

Se presentan casos de estudio para mostrar cómo esta métrica -ayuda a detectar cuando los marcos tienen un problema grave de dependencia de interfaces. Con esta información se puede tomar una decisión cuantitativa para encargarse del problema.

Se muestra además para estos casos de estudio cómo se lleva a cabo la refactonzación de forma automática, utilizando la herramienta diseñada, y las ventajas que se obtienen al hacer este proceso sobre un marco.

Page 14: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Abstract

Object-Oriented programming is one of the current paradigms for producing quality software, providing that the object-oriented design principles are respected and fulfilled. One principle is the interface separation, which states that clients of any given software must not be forced to depend on interfaces they do not need.

Object-Oriented frameworks are sets of classes designed to work together in order to offer generic solutions to many specific problems or offer services within the same application domain. Frameworks must offer methods to extend its functionality and give facilities for reusing sections of the framework in an independent manner.

If an object-oriented framework complies with object-oriented principles, it can be reused and extended without any trouble. If code reuse is achieved, we reduce the time of programming a new application, and also reduce the possibility of defects, since we are using already-proven code.

When frameworks are not well-architectured they do not have these qualities, so it is necessary to obtain them improving the framework architecture. Refactoring is used to change the architecture, which consist on modifying the framework architecture without affecting its functionality.

A situation that often arises from the design of a hmework is the interface dependency problem produced by interface inheritance when subclasses do not really need those interfaces.

When a framework has the interface dependency problem, its functionality cannot be reused separately, and cannot be extended either without violating other object-oriented principles, like the open / close principle.

To solve this problem a refactoring method called Interface Separation is proposed, and its algorithm was successfully implemented in a tool that does automatic refactonng.

Although we know that this problem exists, we do not have a way to measure to what extent this problem affects kameworks. In this dissertation an object-oriented metric to measure the degree of dependency due to unused interfaces is proposed.

Case studies are presented in order to show how this metric helps to detect when frameworks have a serious interface dependency problem. With this information a quantitative decision can be made to take care of the problem.

For these case studies we also show bow to realize the refactoring in an automatic manner, using the designed refactoring tool, and the benefits acquired when this process is done in a framework.

Page 15: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

TABLA DE CONTENIDO

Tabla de Contenido 1

Listado de Figuras 111 ...

Listado de Tablas iv

Glosario de Términos V

Cap. 1. INTRODUCCI~N 1

Cap. 2. ANTECEDENTES 6

2.1. 2.2. Justificación 2.3. Planteamiento del Problema 2.4. Objetivo 2.5.

Estado del Arte y Trabajos Relacionados

Límites y Alcances del Estudio

6 14 14 18 19

Cap. 3. MARCO TEÓRICO 20

3.1. Marco de Aplicaciones Orientado a Objetos (MAOO) 20 3.2. Principios de Diseño Orientado a Objetos 23 3.3. Refactorización 24 3.4. Métricas Orientadas a Objetos 25 3.5. Patrones de Diseño 29

Cap. 4. MÉTODO DE SOLUCIÓN 34

4.1. Refactorización por el Método de Separación de Interfaces 34 4.2. Algoritmo de Separación de Interfaces 37 4.3. Métrica V-DIN0 (Dependencia por Interfaces que No se 40

Ocupan)

Cap. 5. DESARROLLO DEL SISTEMA 43

5. I . Análisis del Sistema 5.2. Diseño del Sistema 5.3. Diseño Detallado del Sistema 5.4. Análisis del Código Fuente 5.5. Herramienta SR2 Refactoring

43 47 51 56 60

Page 16: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Cap. 6. EVALUACIÓN EXPERIMENTAL

6.1. 6.2. 6.3. 6.4.

Cap. 7. CONCLUSIONES Y TRABAJO FUTURO

Anexo A. V-DIN0 como Métrica de Cohesión

Anexo B. V-DIN0 como Escala Ordinal

Caso de Prueba 1: M A 0 0 de Listas Doblemente Ligadas Caso de Prueba 2: M A 0 0 de Estadística Caso de Prueba 3: M A 0 0 de Graficación Caso de Prueba 4: Herramienta de Modelado de Objetos

Anexo C. Análisis del Sistema

Anexo D. Código del Caso de Prueba I

Anexo E. Código del Caso de Prueba 2

Anexo F. Código del Caso de Prueba 3

Anexo G. Código del Caso de Prueba 4

Referencias

67

67 69 72 74

78

82

87

90

103

110

122

132

145

ii

Page 17: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

LISTADO DE FIGURAS

Figura 1 Modelo del SR2 Reingeniería de Software Legado para Reuso Figura 2 Parte del M A 0 0 de Estadística con Tres Operaciones Figura 3 Estructura del Patrón de Diseño ‘Strategy’ Figura 4 Estructura del Patrón de Diseño ‘Template Method’ Figura 5 Estructura del Patrón de Diseño ‘Command’ Figura 6 Estructura del Patrón de Diseño ‘Singleton’ Figura 7 M A 0 0 Refactorizado Usando el Método de Separación de

Interfaces Figura 8 M A 0 0 con Funcionalidad Extendida Figura 9 Ejemplo de un M A 0 0 con Interfaces que no son Mutuamente

Excluyentes Figura I O Diagrama de Casos de Uso Principal Figura 11 Diagrama del Caso de Uso Manejar Archivo Figura 12 Diagrama del Caso de Uso Análisis Sintáctico Figura 13 Diagrama del Caso de Uso Métrica Figura 14 Diagrama del Caso de Uso Generar Arquitectura Figura 15 Diagrama del Caso de Uso Generar Código Figura 16 Arquitectura del Sistema, Jerarquía de Pantallas Figura 17 Arquitectura del Sistema, Jerarquía de Comandos Figura 18 Arquitectura del Sistema, Manejo de Usuarios y Accesos Figura 19 Diagrama de Secuencia para Seleccionar Archivos Originales Figura 20 Diagrama de Secuencia para Calcular la Métrica V-DIN0 Figura 21 Diagrama de Secuencia para Refactorizar Figura 22 Diagrama de Actividades del Proceso de Análisis Figura 23 Diagrama de Actividades del Cálculo de la Métrica Figura 24 Diagrama de Actividades de la Refactorización Figura 25 Modelo Relaciona1 de la Base de Datos Figura 26 Pantalla Principal de SW Refactoring Figura 27 Pantalla de Autenticación de Usuarios Figura 28 Diálogo para Abrir Múltiples Archivos Figura 29 Pantalla de la Métrica V-DIN0 Figura 30 Pantalla del Método de Refactorización Figura 3 1 Pantalla de Comparación de Archivos Figura 32 Pantalla de Registro de Usuarios Figura 33 Pantalla de Tipos de Accesos Figura 34 Diagrama de Clases del Caso de Prueba 1. M A 0 0 Original Figura 35 Diagrama de Clases del Caso de Prueba 1. M A 0 0 Refactorizado Figura 36 Diagrama de Clases del Caso de Prueba 2. M A 0 0 Original Figura 37 Diagrama de Clases del Caso de Prueba 2. M A 0 0 Refactorizado Figura 38 Diagrama de Clases del Caso de Prueba 3. M A 0 0 Original Figura 39 Diagrama de Clases del Caso de Prueba 4. M A 0 0 Original Figura 40 Diagrama de Clases del Caso de Prueba 4. M A 0 0 Refactorizado

7 16 31 31 33 33 35

37 39

44 44 45 45 46 47 48 49 50 51 52 53 54 55 56 59 61 61 62 62 63 64 65 65 68 69 70 71 73 75 76

iii

Page 18: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

LISTADO DE TABLAS

Tabla 1 . Comparación de Herramientas 13 Tabla 2. 41 Caso más Común del Problema de Dependencia de Interfaces Tabla 3 . Comparación de Resultados 77

iV

Page 19: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

GLOSARIO DE TÉRMINOS

ACOPLAMIENTO Es una medida del grado de interdependencia entre módulos, es decir, el modo en que un módulo esta siendo afectado por la estructura interna de otro módulo. I

CLASE ABSTRACTA Es una clase que tiene una o mas interfaces, las cuales no tienen implementación dentro de la clase sino que son implementadas en las clases derivadas de la clase abstracta.

CLASE DERIVADA Es una clase que hereda de una clase abstracta. Esta clase debe implementar todas las interfaces que tenga definidas la clase abstracta.

C-NOC

C O H E S I ~ N

COF

COMMAND

COMPONENTE

Chidamber - Number of Children, Número de Hijos. Es una métrica definida en [Chid941 que representa el número de subclases inmediatas subordinadas a una clase en la jerarquía de clases. Es decir, es una medida de cuántas subclases van a heredar los métodos de la clase padre.

Es una medida del grado de relación que existe entre los elementos que forman a un módulo.

Coupling Factor, Factor de Acoplamiento. Es una métrica definida en [Brit951 que representa la proporción entre el número real de acoplamientos no imputables a herencia y el máximo número posible de acoplamientos en el sistema. Es decir, indica la comunicación entre clases.

I

Comando, patrón de diseño ‘Command’ definido en el catálogo de patrones de diseño de Gamma [Gamm95]. Su intención es encapsular un mensaje como un objeto, !

! con lo que permite parametrizar a los clientes, gestionar colas de mensajes y deshacer operaciones.

Aunque en [Abra011 se establece que no existe un consenso generalizado entre la comunidad de Ingenieros del Software del mundo para definir lo que se entiende por componente, aquí se trata de esclarecer este concepto. [Szip99] define a un

!

V

Page 20: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

CONFIABILIDAD

EFICIENCIA

EXTENSIBILIDAD

FLEXIBILIDAD

FUNCIONALIDAD

INTERFAZ

JAVACC

componente como: “una unidad de composición de software, que puede ser desarrollado, adquirido y utilizado independientemente, y que define las interfaces por medio de las cuáles puede ser ensamblado con otros componentes para proveer y usar servicios”.

Es la capacidad del hardware o software de computación para realizar lo que el usuario espera y hacerlo de manera consistente, sin fallas ni comportamiento errático.

ES un conjunto de atributos que se enfocan en la relación entre el nivel de rendimiento, tanto en tiempo de respuesta como en tiempo de procesamiento, del software y la cantidad de recursos utilizados, bajo ciertas condiciones.

Es una medida de la capacidad que tiene un componente o un sistema de software para aceptar nuevos comandos definidos por el usuario o desarrollador de aplicaciones.

Es el número de opciones que un programador tiene para determinar el uso del componente, también llamado “generalidad”.

Es el grado de funciones que posee el software necesaria y suficientemente para satisfacer las necesidades de un usuario.

También llamada “Función Virtualmente Pura” en el contexto del lenguaje de programación C++. ES un método o función que se declara en una clase pero no se implementa en esa clase.

Es una herramienta generadora de analizadores léxicos y sintácticos escrita en el lenguaje de programación Java y a su vez produce código en Java.

MANTENIBILIDAD Es el grado del esfuerzo requerido para modificar, mejorar o corregir errores en el software con la intención de incrementar la eficiencia o funcionamiento del software.

vi

Page 21: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

MAOO’ I Marco de Aplicaciones Orientado a Objetos. Es un I

conjunto de clases en colaboración que abarca un diseño abstracto para dar soluciones a una familia de problemas relacionados.

MÉTRICA DE SOFTWARE Es una forma estándar de medir algunos atributos de calidad del software. Ejemplos de estos atributos son: cohesión, acoplamiento, tamaño, complejidad, etc.

NFNO

NFV

I I Número de Funciones que No se Ocupan. Es el

número de implementaciones de interfaces con código !

nulo. Sólo existen por cumplir un requisito del compilador, no por ser necesarias.

Número de Funciones Virtuales. Es el número de interfaces que tiene una clase abstracta.

PORTABILIDAD

PATRÓN DE DISENO Es una unidad de información que captura la estructura esencial y la comprensión de una familia de soluciones exitosas probadas para un problema recurrente que ocurre dentro de cierto contexto y sistema de fuerzas.

Es una medida de la facilidad con que un programa determinado podrá funcionar en un ambiente de computación diferente, como una marca de computadora o un sistema operativo distinto.

1 I Martin Fowler en [Fowl991 da dos definiciones del

término dependiendo del contexto: Como nombre o sustantivo: refactorización es “un cambio hecho a la estructura interna de software para hacerlo más fácil de entender y más barato de modificar sin cambiar su comportamiento observable”. Como verbo: refactorizar es la “reestructura de software aplicando una serie de refactorizaciones sin cambiar su comportamiento observable”. En la misma referencia, Fowler reune ambas definiciones en una sola quedando el termino refactorización como: “el proceso de cambiar un sistema de software en tal forma que no se altere el comportamiento externo del código aunque mejore su estructura interna”.

REFACTORIZAR

’ En esta tesis el término M A 0 0 se utiliza para hacer referencia al término en inglés “Framework”, el cual

“Marco de Aplicaciones Orientadd a Objetos”. equivale a los términos en español, I “Marco”, “Marco de Aplicaciones”, “Marco de Componentes Reusables” y

Page 22: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

REUSABILIDAD

SINGLETON

SR2

STRATEGY

Es la habilidad que los productos de software tienen para su reuso, de manera total o en parte, en nuevas aplicaciones. El reuso es cualquier procedimiento que produce o ayuda a producir un nuevo componente de software a partir de un componente ya existente sin modificar a este último.

Patrón de diseño ‘Singleton’ definido en el catálogo de patrones de diseño de Gamma [Gamm95]. Su intención es asegurar que sólo exista una instancia de una determinada clase y proporciona la forma de acceder a ella.

Acrónimo de “Sistema de Reingeniena de Software Legado para Reuso”, proyecto del que este tema de tesis forma parte.

Estrategia, patrón de diseño ‘Strategy’ definido en el catálogo de patrones de diseño de Gamma [Gamm95]. Su intención es definir una familia de algoritmos, encapsula cada uno y los hace intercambiables. Deja que los algoritmos varíen independientemente de los clientes que los utilizan.

TEMPLATE METHOD Método plantilla, patrón de diseño ‘Template Method’ definido .en el catálogo de patrones de diseño de Gamma [Gamm95]. Su intención es definir el esqueleto de un algoritmo en una operación, difiriendo algunos pasos a cada subclase cliente. Deja que las subclases implanten ciertos pasos de un algoritmo sin cambiar la estructura del algoritmo.

USABILIDAD

V-DIN0

Es la medida que establece la facilidad de uso de los componentes por el usuario o desarrollador de aplicaciones.

Valdés - Dependencia por Interfaces que No se Ocupan. Es una métrica definida por primera vez en en [Sant04a] que representa la proporción entre el número real de implementaciones de interfaces con código nulo y el máximo número posible de implementaciones de interfaces en una jerarquía de clases que inicia con una clase abstracta.

viii

Page 23: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 1. Introducción I

Capitulo 1) INTRODUCCI~N

El paradigma de programación orientada a objetos representa uno de los modelos de desarrollo más actuales y, que tiene las mayores ventajas para alcanzar una mayor productividad de los programadores y diseñadores de software, así como que el software resultante se considere que cuenta con calidad aceptable [Sant02].

Este paradigma provee muchos beneficios, tales como reuso, descomposición de problemas en objetos fáci1,mente entendibles y también la facilidad para llevar a cabo futuras modificaciones o .extensiones de funcionalidad en sistemas existentes. Los lenguajes orientados a objetos soportan el reuso por medio de la jerarquía de clases, así como por medio de la instdnciación y uso de entidades previamente definidas.

El reuso se define como el uso de conceptos u objetos adquiridos previamente en una nueva situación, que involucra la representación de información de desarrollo en diferentes niveles de abstracción, el almacenamiento de esta representación para referencias futuras, la comparación de situaciones nuevas y viejas, la duplicación de objetos y acciones ya desamoliadas, y la adaptación para cumplir nuevos requerimientos [Bigg89]. I

1

Page 24: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 1. Introducción

La calidad del software, su confiabilidad, y productividad, deben mejorar cuando 10s programas, diseños, especificaciones, etc., son reusados. El reuso de software reduce la cantidad de software que debe ser desarrollado desde cero, y por tanto permite un mayor enfoque en la calidad. El reuso de software ya probado provoca mayor confiabilidad y el alto costo de verificación de un módulo reusable puede dividirse sobre las varias aplicaciones que lo utilicen. Con el reuso, el desarrollo de software se convierte en una inversión primaria. El esfuerzo de desarrollo de cada aplicación es utilizado para construir una infraestructura de software que puede ser aplicada en sistemas futuros [Biem92].

Una buena práctica de implementar programas orientados a objetos es construyendo marcos de aplicaciones orientados a objetos (que en io sucesivo serán denominados MAOO’s). Los MAOO’s son un conjunto de clases trabajando juntas en un cierto dominio de problemas, ofreciendo soluciones genéricas que pueden ser adaptadas a muchos problemas específicos dentro del mismo dominio.

Un M A 0 0 es más que una jerarquía de clases. Es una aplicación semi-completa que contiene componentes dinámicos y estáticos que pueden ser personalizados para producir aplicaciones específicas. Se consideran semi-completos los MAOO’s porque les falta una interfaz de usuario que utilice la funcionalidad ya establecida y porque se pueden especializar. Debido a la naturaleza genérica de los MAOO’s, los MAOO’s maduros pueden ser reusados como base para muchas más aplicaciones [FayaOO].

Sin embargo, cuando los MAOO’s son creados o están en las primeras etapas de desarrollo no siempre cuentan con arquitecturas perfectas, por lo que es necesario implementar varios métodos de refactorización que permitan mejorar y controlar la evolución de estos MAOO’s, para alcanzar una mayor cobertura del dominio, con arquitecturas más flexibles y adaptables a nuevos usos o aplicaciones.

Asimismo, en la actualidad existen procesos de reingeniería para cambiar el software que no utiliza el paradigma orientado a objetos a una estructura que ya utilice este modelo. Sin embargo, la aplicación de esta tecnología de manera fría sin la intervención de un experto en el dominio, resulta en arquitecturas reestructuradas pero no perfectas, por lo que es necesario implementar varios métodos de refactorización que permitan mejorar y controlar la evolución de MAOO’s, para alcanzar una mayor cobertura del dominio, con arquitecturas más flexibles y adaptables a nuevos USOS O aplicaciones [Sant02].

La tarea de la reingeniería es recuperar información acerca de la estructura de un sistema, su funcionalidad, diseño y comportamiento dinámico; con la finalidad de poder hacer cambios, obteniendo mejores módulos y arquitecturas con un mantenimiento menos costoso.

Dentro de los diseños problemáticos de los MAOO’s existe uno en particular hacia el cual se enfoca este trabajo; este problema es el de las dependencias de interfaces por utilizar algunas de éstas aunque en realidad no se ocupan. Este problema es muy grave ya que aquellos MAOO’s que lo presentan no pueden extender su funcionalidad e impide que los MAOO’s sean reusados en otros contextos, perdiéndose así el objetivo de emplear MAOO’s.

El problema se analiza con las funciones virtualmente puras de C++ que sirven como interfaces del MAOO; estas funciones se encuentran en clases bases abstractas y las clases derivadas de estas clases abstractas deben de implementarlas. Aquí se puede

2

Page 25: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capitulo 1. Introducción

dar el caso donde estas interfaces no se ocupen, pero tienen que ser declaradas vacías para evitar problemas de compilación, creando asi una dependencia.

Para resolver este problema de dependencia de interfaces se necesita hacer una reorganización de las clases del MAOO, realizando así un proceso conocido como refactorización, el cual consiste en hacer cambios a la arquitectura de un sistema sin modificar su funcionalidad.

Existen ya herramientas que hacen refactorizaciones sobre código C++, algunas básicas y otras complejas, pero ninguna ha contemplado el problema de dependencia de interfaces. Debido a la trascendencia y repercusiones de este problema, nos dimos a la tarea de resolverlo, lográndlolo satisfactoriamente.

Para ello en esta te'sis se creó una herramienta que realiza refactorizaciones a MAOO'J escritos en lenguaje C++ y que forma parte del proyecto SR2 [SantOZ]. Este proyecto tiene como objetivo transformar código procedural escrito en lenguaje C hacia código orientado a objetos en C++, y posteriormente se refina este código utilizando refactorizaciones.

Esta herramienta apkrte del método de refactorización que resuelve el problema de dependencia de interfaces, incorpora otros dos métodos de refactorización: uno para resolver el problema de alta dependencia entre clases debido a la gran cantidad de canales de comunicación [Card041 y otro para resolver el problema de incompatibilidad de interfaces entre un M A 0 0 y un cliente [Sant04e].

Como se mencionó' anteriormente, el paradigma de programación orientada a objetos ofrece múltiples beneficios, sin embargo, el ciclo de desarrollo de software orientado a objetos no es más fácil que el desarrollo procedural., Por io tanto es necesario proveer de guías confiables que se puedan seguir para realizar buenas prácticas de programación orientada a objetos y escribir código confiable.

Una de las maneras de proveer estos lineamientos es el uso de métricas orientadas a objetos, las cuales son consideradas un estándar con las que se puede medir la efectividad de las técnicas orientadas a objetos en el diseño de un sistema. Estas métricas pueden ser aplicadas para analizar código fuente y poder obtener atributos de calidad [Bera03].

En esta tesis también se propone una métrica orientada a objetos que cuantifique el grado de dependencia debido a interfaces que no se ocupan. El grado de dependencia es un problema importante que debe ser tratado porque afecta directamente a la capacidad de un M A 0 0 para soportar modificaciones futuras y la extensión de nuevas funcionalidades.

Organización de este documento de tesis: A continuación se da un !panorama de la organización de este documento, el cual describe el trabajo que se realizó para sustentar, diseñar y constmir la herramienta de refactorización y para diseñar la métrica propuesta en esta tesis.

Dentro del capítulo 2, en la sección 2.1, se da una panorámica crítica de los trabajos comerciales y de laboratorio más representativos que se enfocan en la misma linea de este trabajo de tesis, desde diferentes perspectivas y con diferentes criterios de refactorización. 1

En la sección 2.2 se 'da una justificación del estudio desde el punto de vista de la refactorización de MAOO's con el problema de dependencia de interfaces y desde el punto de vista de la necesidad de contar con una métrica que mida dicho problema.

I

i 3

Page 26: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 1. Introducción

En la sección 2.3 se plantea el problema de dependencia de interfaces por interfaces que no se utilizan, y se explican las consecuencias de este problema. Además se menciona la estrategia o enfoque propuesta e implementada para resolverlo.

En la sección 2.4 se define el objetivo a perseguir en la solución al problema planteado de este trabajo de tesis.

Por Último, en la sección 2.5, se mencionan los alcances y las limitaciones de esta tesis.

En el capítulo 3 se exponen en general, los tópicos teóricos o el marco de conocimientos en los que se apoya la solución planteada en esta tesis.

Se expone un resumen de la programación orientada a objetos y los marcos de aplicaciones orientados a objetos, los principios del diseño orientado a objetos y de refactorización, se ofrece también el fondo matemático sobre las métricas orientadas a objetos en general y las bases de la métrica diseñada, y por último se tiene una sección sobre patrones de diseño, donde se especifican las definiciones de los patrones de diseño ‘Template Method’ y ‘Strategy’, que fueron empleados en el método de refactorización, incluyendo también la descripción de los patrones ‘Command’ y ‘Singleton’ que fueron utilizados en la elaboración de la interfaz de la herramienta.

En el capítulo 4 sección 4.1, se explica el método de refactorización, basado en el principio de Separación de Interfaces, utilizando para esta explicación un ejemplo que se desarrolla paso a paso.

En la sección 4.2 se explica el algoritmo de solución propuesto para resolver el problema planteado en esta tesis, denominado Separación de Interfaces.

La sección 4.3 explica la métrica orientada a objetos propuesta en este trabajo, denominada V-DINO, Dependencia por interfaces que No se Ocupan. También se explica cómo calcularla y cómo interpretar el resultado que arroja dicha métrica.

En el capítulo 5 se explica todo el ciclo de vida del sistema creado para implementar el método de refactorización y la métrica. Este sistema cuenta con características para contener otros métodos y métricas.

Primeramente, en la sección 5.1, se presenta el análisis del sistema, utilizando para ello los diagramas de casos de uso con su documentación propuesta por UML (Unified Modeling Language).

En la sección 5.2 se presenta el diseño general del sistema, usando diagramas de clases de UML, y se presenta una explicación del por qué de la estructura del sistema y los patrones utilizados en ella.

En la sección 5.3 se presenta parte del diseño detallado del sistema, con la funcionalidad más importante del mismo, explicada a base de diagramas de secuencia y actividades de UML.

En 5.4 se expone el proceso de análisis de código fuente, escrito en lenguaje C++, que se aplica para extraer información útil en cuanto a las entidades, atributos y operaciones del dominio en exploración y las relaciones que existen entre estos, para aplicarle la métrica y la refactorización. Para hacer este análisis se utilizó el metalenguaje JavaCC.

En la sección 5.5 se presenta la interfaz del sistema, cuya arquitectura fue explicada en la sección 5 .2 , y se explica cómo puede ser extendida para agregar más métodos de refactorización y métricas, en especial dos métodos ya incorporados que fueron producto de otras tesis de maestría del cenidet. También aquí se describe la

4

Page 27: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 1. Introducción ~

implementación del método de refactorización por Separación de Interfaces y la métrica V-DINO dentro del sistema.

En el capítulo 6 se describe un conjunto de documentos de prueba que están asociados con los aspectos dinámicos de las pruebas del sistema.

Aquí se da una descripción de cómo se efectuó la investigación experimental. Se distinguen las características de los casos de estudio, el diseño, y la definición de los casos de estudio, para la prueba del proceso de análisis de código fuente, del cálculo de la métrica, y del proceso de refactorización, así como los resultados obtenidos como producto del análisis de 1oJ datos de salida del proceso de evaluación.

En el capítulo 7, se derivan las conclusiones a que se llegó después de analizar, diseñar, instrumentar y probar el sistema.

Aquí se realiza un análisis de las implicaciones del estudio, y si se cumplieron parcial o totalmente los objetivos planteados en la propuesta del proyecto de tesis. También se describen los trabajos publicados producto de esta tesis, tanto en el aspecto del método de refactorización como en el aspecto de la métrica, así como publicaciones de otros trabajos realizados durante el periodo de elaboración de esta tesis.

Como un punto final se da un resumen de recomendaciones para otras investigaciones en la misma dirección de este proyecto de tesis y para complementar el sistema SR2 con más métodos de refactorización, métricas orientadas a objetos y tecnología de Servicios Web.

5

Page 28: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes

Capitulo 2) ANTECEDENTES

2.1. Estado del Arte y Trabajos Relacionados Esta tesis es parte de un proyecto más grande denominado SR2: Reingeniería de Software Legado para Reuso, propuesto por el área de ingeniería de Software del cenidet [Sant02].

El enfoque que se ha dado a este proyecto es la obtención de marcos de aplicaciones orientados a objetos a partir de la reingeniería de software legado escrito en lenguaje C, lo cual permitiría ampliar el tiempo de vida útil de este software y la recuperación de la inversión en su desarrollo.

El SR2 consiste básicamente en plantear un modelo que contempla un proceso de reingeniería de software legado de tres etapas para la creación y mantenimiento automatizado de MAOO’s [Sant03].

La primera etapa consiste en el análisis de código fuente para recabar información y poder reestructurar el código legado. La segunda consiste en la reestructura del código fuente original hacia MAOO’s, escritos en lenguaje C++, mejorando su diseño y obteniéndose arquitecturas reusables. Por último, la tercera etapa consiste de un sistema de refactorización, para el refinamiento sucesivo de los MAOO’s

6

Page 29: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes I

obtenidos desde el proceso de reestructura [Sant03]. El modelo de este proyecto se muestra en la Figura 1.

M d e l o del SR2 Reiiqenleiia de Sc>Amaie Legado paia Reuso

._..............._...................

I’ ’

. ‘ I . ,

Figura 1. Modelo del SR2 Reingeniena de Software Legado para Reuso

La tesis que se propone en este documento forma parte de la última etapa del modelo que presenta el SR2.

Para cumplir las tres etapas del proyecto SR2 se han realizado y se continúan realizando varias tesis dentro y fuera del cenidet, tanto de doctorado, maestría e incluso

A continuación se mencionan las tesis que hasta la fecha han sido derivadas de este proyecto, incluyendo la que se propone aquí, indicando quién la realiza, de qué institución es, y a qué grad,o pertenece.

1. “Modelo de Representación de Patrones de Código para la Construcción de Componentes Reusables”. René Santaolaya Salgado, CIC-IF”, tesis de doctorado ya terminada.

2. ”Identificación de Funciones Recurrentes en Software Legado”. Anel Sheydi Zamudio López, CENIDET, tesis de maestría ya terminada.

3. ”Concepción de un Modelo para el Aseguramiento de Calidad de Componentes Reusables de Software”. Javier Santa Olalla Salgado, CIC-IPN, tesis de maestría ya terminada. j

4. ”Sistema de Pruebas de Calidad de Componentes Reusables”. Blanca R. Olascoaga Vergaraj CIC-IPN, tesis de maestría en desarrollo.

5 . ”IPADIC++: Sistema para Identificación de Patrones de Diseño en Código C++”. Agustín F. Castro Espinoza, CENIDET, tesis de maestría ya terminada.

6 . “Factorización de Código en C para Reuso”. Arely Pérez Aparicio, CENIDET, tesis de maestría en desarrollo.

7. “Factorización de F c i o n e s en Métodos de Plantilla”. Laura Alicia Hernández Moreno, CENIDET, tesis de maestría ya terminada.

de licenciatura. I

7

Page 30: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes

8. ‘‘Sistema Documentador de Frameworks Basado en Componentes”. Ruth Barrera Sosa, 1.T. Moreha, tesis de licenciatura ya terminada.

9. “Reestructuración de Código Legado a partir del Comportamiento para la Generación de Componentes Reutilizables”. César Bustamante Laos, CENIDET, tesis de maestría ya terminada.

10. “Sistema para la Administración de la Configuración de Componentes de Software”. Jorge Ernesto Aranda Camacho, CIC-IPN, tesis de maestría suspendida.

11. “Reconocimiento de Patrones de Diseño de Gamma a partir de la Forma Canónica definida en el IPADIC++”. Patricia Zavaleta Carrillo, CENIDET, tesis de maestría ya terminada.

12. “Refactorización de Marcos Orientados a Objetos para Reducir el Acoplamiento Aplicando el Patrón de Diseño Mediator”. Leonor Adriana Cárdenas Robledo, CENIDET, tesis de maestría ya terminada.

13. “Reestructuración de Software Escrito por Procedimientos Conducido por Patrones de Diseño Composicionales”. Armando Méndez Morales, CENIDET, tesis de maestría ya terminada.

14. “Integración de la Funcionalidad de Frameworks Orientados a Objetos”. Juan José Rodriguez Gutiérrez, CENIDET, tesis de maestría ya terminada.

15. “Adaptación de Interfaces de Marcos de Aplicaciones Orientados a Objetos, Utilizando el Patrón de Diseño Adapter”. Luis Esteban Santos Castillo, CENIDET, tesis de maestna ya terminada.

16. “Método de Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de interfaces”, Manuel Alejandro Valdés Marrero, CENIDET, presente tesis de maestría.

En esta sección nos enfocaremos a trabajos relacionados con la refactorización de código orientado a objetos, que es la parte medular de esta tesis.

A grandes rasgos, la refactorización es el proceso de hacer transformaciones a programas para hacer cambios de la estructura de clases a nivel de diseño [Robe97].

La refactorización no cambia el comportamiento de un programa, esto es, si el programa es ejecutado dos veces (antes y después de la refactorización) con la misma entrada; la salida será la misma. Las refactorizaciones preservan el comportamiento para que, cuando las precondiciones de la refactorización sean cumplidas, no hagan que falle el programa [Opdy92].

A continuación se mencionan algunos trabajos sobre refactorización de MAOO’s aplicando patrones de diseño creacionales, estructurales y de comportamiento en la arquitectura de un M A 0 0 y que resuelven problemas similares al descrito en este trabajo, pero con enfoques diferentes.

Lance Tokuda y Don Batory ‘University of Texas a t Austin’, Austin, USA Los proyectos que están desarrollando estos investigadores están enfocados hacia la refactorización de código en C++.

Se utilizan tres tipos de refactorización, y la decisión sobre el hecho de ejecutar o no la transformación es tomada por el usuario.

8

Page 31: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes I La primera refacto+ación trata sobre modificaciones de estructura denominadas

primitivas, que consisten en pequeños cambios al diseño de un MAOO, como pueden ser: cambios de nombres de variables, de clases o de métodos, agregación de clases, de métodos, etc.

La segunda refactorización es sobre estructuras propias de C++, como la transformación de un tipo de dato estructura a una clase.

La tercer refactorización trata sobre llevar ciertas arquitecturas defectuosas a una mejor estructura utilizando patrones de diseño. Los patrones que utiliza son de los tres tipos descritos en el catálogo de Gamma: Dentro de los creacionales utiliza ‘Factory Method’, ‘Singleton’ y ‘Abstract Factory’; dentro de los estructurales utiliza ‘Composite’ y ‘Decorator’; y dentro de los de comportamiento utiliza ‘Iterator’, ‘Command’ y ‘Visitor’.

En esa investigación se hace la mención de que es factible implementar la refactorización con otros eatrones de diseño de Gamma. Esta refactorización sería con: ‘Adapter’, ‘Bridge’, ‘Builder’, ‘Strategy’ y ‘Template Method’.

I .

Algunas publicaciones que se han hecho sobre este trabajo son: “Automated Software Evolution via Design Pattern Transformations” [Toku95] “Design Evolution with Refactorings” (Ph.D Tokuda) [Toku99] “Automating three Models of Object-Oriented Software Evolution” [Toku99a] “Evolving Object-Oriented Design with Refactorings” [TokuOI]

La diferencia que existe entre estas investigaciones y lo propuesto en esta tesis es que en estas investigaciones no se plantea la solución del problema de la dependencia de interfaces, sólo se protone como trabajo a futuro hacer una refactorización con los patrones ‘Strategy’ y ‘Template Method’. Otra diferencia es que para hacer una refactorización esta herramienta ocupa mucha interacción con el usuario, por io que no se podría considerar que el proceso sea totalmente automatizado.

William C. Chu, Chih-Wei Lu, Chih-Peng Shiu y Xudong He ‘Tung Ha¡ University’ & I‘Feng Chia University’, Taichung, Taiwan Los proyectos que están realizando estos investigadores están enfocados a la reestructura y refactorizactón de aplicaciones específicas de código legado en C hacia el lenguaje Java.

La reestructura de código legado hacia código orientado a objetos, así como la refactorización, es realizada de forma manual.

La refactorización ‘que llevan a cabo emplea .algunos patrones de diseño del catálogo de Gamma: Deniro de los creacionales utiliza ‘Factory Method’ y ‘Builder’; dentro de los estructurales! utiliza ‘Adapter’, ‘Bridge’, ‘Composite’ y ‘Proxy’; y dentro de los de comportamiento utiliza ‘Chain of Responsability’, ‘Command’, ‘Iterator’, ‘Mediator’, ‘Observer’, ‘State’ y ‘Strategy’.

1. 2. 3. 4.

Una publicación qui trata sobre este trabajo es: “Pattern-Based Sofiware Reengineering: a Case Study” [ChuWOO]

La diferencia que existe entre esta investigación y lo propuesto en esta tesis es que en esta investigación:la refactorización se hace de manera manual, y aunque se

1. I

I

I 9

Page 32: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes

utiliza el patrón de diseño ‘Strategy’, no existe una referencia que mencione que se utilice este patrón para hacer separación de interfaces.

Me1 Ó Cinnéide, Paddy Nixon y Mark O’Keeffe ‘University College’ & ‘Trinity College’, Dublin, Ireland Este proyecto es bastante completo y su objetivo es refactorizar código en Java. Para cumplir este objetivo, crearon una herramienta llamada Design Pattern Tool (DPT) y un lenguaje llamado LDPT para hacer la especificación de las refactorizaciones.

El proceso de refactorización lo realiza de manera automática, ya que la herramienta tiene implementada la validación de las precondiciones que se deben cumplir antes de aplicar un método de refactorización.

Los patrones de diseño que implementaron en su herramienta son todos los creacionales: ‘Abstract Factory’, ‘Factory Method’, ‘Builder’, ‘Singleton’ y ‘Prototype’; aparte se implementó el patrón de diseño estructural ‘Decorator’ del catálogo de Gamma.

Los creadores de esta herramienta tienen bastantes publicaciones con muchas aportaciones, como por ejemplo: En [OCinOl] se presenta un análisis de cómo hacer refactorizaciones automáticas con un gran número de patrones, y se hizo una herramienta automática para los patrones ‘Abstract Factory’, ‘Factory Method’, ‘Singleton’, ‘Builder’, ‘Prototype’, ‘Bridge’ y ‘Strategy’.

Y en [OKefü3] se presenta el prototipo de la herramienta Deartbóir, que sirve para hacer refactorizaciones utilizando métricas. Por el momento sólo tiene la funcionalidad de mover métodos a su posición óptima en una jerarquía de clases, pero los autores afirman que se le agregarán más refactorizaciones, incluso con patrones y, más métricas. El objetivo final es tener una herramienta automática que mejore el diseño de un sistema en Java.

Algunas publicaciones que se han hecho sobre este trabajo son: “Towards Automating the Introduction of the Decorator Pattern to Avoid Subclass Explosion” [OCin96] “Program Restructuring to Introduce Design Patterns” [OCin99] “Automated Application of Design Patterns to Legacy Code” [OCin99a] “Composite Refactorings for Java Programs” [OCinOO] “Automated Refactoring to introduce Design Patterns” [OCinOOa] “Automated Application of Design Patterns: a Refactoring Approach” (Ph.D Ó Cinnéide) [OCinOl] “A Stochastic Approach to Automated Design Improvement” [Okefü3]

La diferencia que existe entre estas investigaciones y lo propuesto en esta tesis es que en estas investigaciones no se plantea el problema de tener que hacer una separación de interfaces, sino que enfocan su trabajo hacia los problemas de creación de objetos y estructura de los MAOO’s.

William F. Opdyke ‘University of Illinois at Urbana-Champaign’, Urbana, USA Este investigador es considerado uno de los pioneros de la refactorización y su trabajo, ha servido de base para muchos otros, dentro y fuera de la universidad donde trabaja.

1.

2. 3. 4. 5. 6 .

7.

10

Page 33: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes

Su trabajo consist en una suite de refactorización para lenguaje C++, donde introduce ocho refactorizlciones básicas: Definir una superclase abstracta de una o más clases existentes; especializar una clase definiéndole subclases, y usar este método para eliminar condicionales; cambiar la asociación entre clases, de herencia a composición; mover una clase a travésidel árbol de herencia; mover variables y métodos miembro; reemplazar un segmento de código por una llamada a una función; cambiar el nombre de clases, variables y funciones; reemplazar el acceso sin restricción a variables miembro por una interfaz más abstracta.

Para llevar a cabo estas refactorizaciones, Opdyke definió 26 refactorizaciones de bajo nivel: tres para crear entidades, tres para borrar una entidad, 15 para modificar a una entidad, dos para mover una variable miembro, una para mover una clase, otra para el acceso a las variables y! una más para convertir un segmento de código en función; y tres refactorizaciones dás abstractas: definir superclases abstractas, simplificar condicionales usando subClases, y crear agregaciones y componentes reusables.

También definió la manera de cómo hacer de manera automatizada la refactorización, manejandb las precondiciones y poscondiciones de una refactorización.

En este trabajo no se emplean patrones de diseño, pero se menciona que se puede crear este tipo de refactorizaciones a partir de las primitivas que están implementadas.

Algunas de sus pudlicaciones que refieren a refactorización son: “Refactoring Object-Oriented Frameworks” (Ph.D Opdyke) [Opdy92] “Creating Abstract’Superclasses by Refactoring” [Opdy93]

“Lifecycle and Refactoring Patterns that Support Evolution and Reuse” [Foot941

1. 2. 3. “Refactoring and Iggregation” [John931 4.

I

La diferencia que existe entre esta investigación y lo propuesto en esta tesis es que en la primera no se busca refactorizar utilizando patrones de diseño, sino sólo se hacen refactorizaciones simples o primitivas, que al utilizarlas en conjunto podrían crear una refactorización de un patrón de diseño. Tampoco están enfocadas sus refactorizaciones hacia redolver problemas de diseño o aumentar la capacidad de reuso, sino sólo están enfocada4 a hacer pequeñas modificaciones al código con el fin de hacerlo más legible.

John Brant, Brian Foote! Ralph E. Johnson, Donald Roberts, Alejandra Garrido ‘University of Illinois at Urbana-Champaign’, Urbana, USA Este grupo es de los más productivos en cuanto a artículos técnicos se refiere y tienen mucho tiempo investigando sobre refactorización. Trabajan en conjunto con Opdyke, utilizando las refactorizaciones creadas por él, pero implementadas para el lenguaje orientado a objetos Smalltalk.

Dentro de sus proyectos, se creó una herramienta para hacer refactorizaciones de forma automatizada, Ilamdda Refactoring Browser.

Esta herramienta diliza la mayoría de las refactorizaciones de Opdyke, excepto las que son exclusivas ~ de C++ y no tienen equivalente en Smalltalk. Cada refactorización es comprobada verificando que las precondiciones y poscondiciones se cumplan.

Con todas las primitivas se creó una refactorización compleja para el patrón de

I

diseño de comportamiento ‘Visitor’ del catálogo de Gamma. 0 4 - 0 8 3 4

11

i

Page 34: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes

Los creadores de la herramienta Refactoring Browser ahora se dedican más a consultoria y dirección en la Universidad de Illinois en Urbana Champaign y a través de su compañía Refactory Inc.

Uno de los trabajos actuales que están dirigiendo es CRefactory [Garr04], que es una herramienta para reestructurar y refactorizar de C a C++ utilizando las refactorizaciones básicas de [Robe97]. La principal aportación de este trabajo es el manejo de las directivas de pre-procesador, lo cual aún no se tiene implementado en SR2.

1. 2.

3.

4.

5 . 6 . 7. 8. 9. 1 o.

Algunas de las publicaciones de los miembros de este grupo son: “Designing Reusable Classes” [John881 “Designing to Facilitate Change with Object-Oriented Frameworks” (Masters Foote) [Foot881 “An Object-Oriented Framework for Reflective Meta-level Architectures” (Ph.D Foote) [Foot951 “Evolving Frameworks, a Pattern Language for Developing Object-Oriented Frameworks” [Robe961 “A Refactoring Tool for Smalltalk” [Robe971 “Why every Smalltalker should use the Refactoring Browser” [Robe981 “Wrappers to the Rescue” [Bran981 “Practical Analysis for Refactoring” (Ph.D Roberts) [Robe991 “Refactoring C with Conditional Compilation” [Garr03] “Program Refactoring in the Presence of Preprocessor Directives” (Ph.D Garrido) [Garr04]

La diferencia que existe entre estas investigaciones y lo propuesto en esta tesis es que en las primeras se utilizan refactorizaciones simples o primitivas para cambiar el aspecto de un MAOO, pero no para resolver algunos problemas de diseño que pudiera tener. Se emplean las refactorizaciones primitivas para formar las refactorizaciones complejas que se necesitan para implementar un patrón de diseño, pero aún no han avanzado mucho en este sentido.

J. Kerievsky Industrial Logic, Inc., USA Este trabajo es un libro en progreso apoyado por Industrial Logic Inc., en donde se explora la relación que existe entre la refactorización y los patrones, y detalla varias refactorizaciones en forma manual que muestran cómo llegar a los patrones de diseño siguiendo un algoritmo. Utiliza los patrones de diseño del catálogo de Gamma: ‘Singleton’, ‘Factory Method’, ‘Strategy’, ‘Composite’, ‘Builder’, ‘Decorator’, ‘Proxy’, ‘Observer’, ‘Adapter’, ‘State’, ‘Template Method’, ‘Visitor’ y ‘Flyweight’.

Este trabajo si contempla el problema de dependencia de interfaces por tener interfaces que no se utilizan, pero lo intentan solucionar de una manera diferente utilizando el patrón ‘Adapter’.

Una evaluación de su método de solución muestra que no resuelven completamente el problema, pero si lo aligeran en las clases derivadas, ya que suben el problema de implementaciones vacías a un adaptador que colocan antes de la clase base original.

12

Page 35: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capitulo 2. Antecedentes ,

La publicación que /rata sobre este trabajo es: 1. “Refactoring to Patterns” [Keri03]

La diferencia que existe entre estas investigaciones y lo propuesto en esta tesis es que se toma un enfoque diferente para resolver el problema. Aunque su método de refactorización tiene menqs precondiciones que el propuesto aquí, no es efectivo, ya que sólo disfraza el problema de las implementaciones vacías, pero no lo elimina. Además sólo proponen un algoritmo y la forma manual de resolución, pero no hay intenciones de construir una herramienta que haga la refactorización automática.

Leonor A. Cárdenas, Juan J. Rodriguez, Manuel Valdés y Luis E. Santos ‘Centro Nacional de Investigación y Desarrollo Tecnológico’, Cuernavaca, México Dentro de la fase de refactorización del proyecto SR2 existen otras tres tesis que, junto con la que se describe en 4ste documento, se enfocan a problemas específicos de diseño que presentan algunos MAOO’s, y al combinarse todas estas tesis se tendrá la posibilidad de resolver und amplia variedad de problemas. Los problemas que se tienen contemplados hasta el momento son los de: alta dependencia entre clases por la gran cantidad de canales de codunicación [CardO4], integración de la funcionalidad de dos o más MAOO’s [Rodr04]! y adaptación de interfaces por incompatibilidad de componentes entre un M A 0 0 y sus clientes [Sant04e].

Estos trabajos se enfocan a problemas específicos de diseño que presentan algunos MAOO’s, y al combinarse todos se tendrá la posibilidad de resolver una amplia variedad de problemas. Ellos en conjunto utilizan los patrones de diseño ‘Mediator’, ‘Observer’ y ‘Adapter’.

Recordando que en esta tesis, que resuelve el problema de dependencia de interfaces por implementar interfaces que no se ocupan, se utilizan las estructuras de los patrones de diseño de comportamiento ‘Strategy’ y ‘Template Method’, del catálogo de Gamma, para refactorizar MAOO’s por la Separación de Interfaces, se hará un análisis de la información recabada para compararla contra la presente tesis.

En la Tabla 1 se muestra un resumen comparativo entre todos los gmpos de trabajo y herramientas presentadas anteriormente, donde se muestra si la herramienta trabaja de manera automitizada, qué lenguaje es el que refactoriza, si implementa patrones de diseño y cuánios, y si utiliza los patrones de diseño ‘Strategy’ y ‘Template Method’.

Tabla 1: Comparación de Herramientas Herramienta I Automática I Lenguaje 1 Patrones I Strategy y I Separación I

I I I Diseño I Temolate I de I

I 13

Page 36: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capitulo 2. Antecedentes

Como se muestra en la Tabla 1, la herramienta que se propone tiene características que no tiene ninguna herramienta examinada. Esto es que ninguna implementa el método de Separación de Interfaces, y la única herramienta que sí considera la separación de interfaces no utiliza los patrones de diseño ‘Strategy’ y ‘Template Method’ y hace la refactorización de forma manual.

Por tanto se concluye que la solución al problema que se plantea en esta tesis no ha sido implementada por los trabajos publicados que fueron consultados para efecto de referencia.

2.2. Justificación De los trabajos de investigación que se consultaron sobre la reestructura de software legado muy pocos van dirigidos hacia la construcción de MAOO’s (marcos de componentes reusables de aplicaciones orientados a objetos), de éstos últimos unos cuantos aplican patrones de diseño del catálogo de Gamma. Y ninguno de ellos incorpora un método que resuelva el problema planteado, desde el punto de vista de aplicar los patrones de diseño ‘Strategy’ y ‘Template Method’.

Con la dependencia de interfaces que no se ocupan, se disminuye las cualidades de extensión y reuso de un MAOO, de ahí que el objetivo sea minimizar esta dependencia, de modo que una clase sólo tenga las interfaces que necesita.

Con la refactonzación se puede mejorar la arquitectura de un M A 0 0 sin modificar su funcionalidad. Lo que se logra con esto no son beneficios para el M A 0 0 actual, sino beneficios para futuras extensiones o nuevos usos que se le den al MAOO, ya que la refactorización incrementa las cualidades de reuso y extensión, que son aspectos a considerar para mejorar la calidad de un producto de software [ISO91].

Con la herramienta creada se pueden resolver o aminorar problemas específicos de diseño de MAOO’s que están siendo usados en el ámbito profesional, lo que traerá una disminución de costos para el mantenimiento o cuando se hagan futuros esfuerzos sobre el MAOO. Este trabajo incorpora beneficios no mostrados por otras herramientas o métodos de refactorización ([Keri03], [Garr04], y [Robe97]) en cuanto a la automatización del proceso de refactorización, la evaluación de precondiciones, para ver si es posible realizar la refactorización, y el uso de patrones de diseño.

Este trabajo también sirvió como base para crear la métrica orientada a objetos V-DIN0 [Sant04a] para medir el grado de dependencia de interfaces en un MAOO. Esta métrica es usada para determinar cuándo es posible y factible emplear el método de refactorización por Separación de Interfaces. Se hizo la métrica ya que basta ese momento no existía una manera de medir el problema de dependencia por interfaces que no se ocupan.

2.3. Planteamiento del Problema Un problema que presentan algunos MAOO’s es que su arquitectura obliga a 10s clientes a depender de interfaces que no utilizan, y éstos se ven afectados al ser modificadas estas interfaces, es decir, se tiene un alto grado de dependencia. Esta dependencia se debe evitar, separando las interfaces donde sea posible.

El problema se presenta con ciertas relaciones de herencia, donde las subclases tienen un alto grado de dependencia con la clase abstracta. Esto se produce por la declaración de interfaces o funciones virtuales puras que sus clases derivadas en realidad no ocupan.

14

Page 37: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes

...

class Nombre-Clase ... { ... virtual tipo-retorno ...

I ... }; // Termina definición de, la clase y como se mencionó pueden tener código dentro de ellas o no pueden tenerlo, pero sí deben abrirse y cerrarse la; llaves { } .

Las funciones virtuales puras son funciones declaradas en una clase base abstracta sin implementación en esta clase, sino que todas las clases hijas de la clase abstracta deben implement+rlas. En los casos en que la clase hija no ocupa o necesita la función, de todos modos debe implementaria sin código porque no la ocupa. Dentro de la especificación de una clase, las declaraciones de funciones virtuales puras en el lenguaje C++ son de la sighente manera:

y como se dijo, no existe una implementación de esta función dentro de la propia clase; por lo tanto debe estar implementada en la totalidad de sus clases derivadas.

Las interfaces so,n funciones virtuales puras o vacías de código de implementación, declaradas en una clase base abstracta y todos los hijos de la clase abstracta deben implementarlas, aunque sea sin código porque no las ocupan.

Las funciones vacías están ahí debido a que una clase tiene que satisfacer un contrato heredando de un4 clase abstracta, pero en realidad sólo necesita código para

I

virtual tipo retorno Nombre Funcion (parámetros) = O; - I _ - . .

Nombre-Funcion (parámetros);

15

{ ... /I código ...

Page 38: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes

algunas funciones de la clase abstracta. El resto de las funciones son implementadas pero permanecen vacías: sólo fueron añadidas para satisfacer una regla del compilador. Estas funciones vacías hacen que crezca la interfaz de una clase (es decir, hay más funciones públicas), informan de manera falsa sobre el comportamiento de una clase (Una clase puede supuestamente ejecutar los métodos X(), Y() y 20, pero sólo provee código para XO), y obligan a hacer trabajo extra (como declarar funciones vacías en extensiones) [Keri03].

A continuación se muestra un ejemplo de un pequeño M A 0 0 para ilustrar el problema de dependencia de interfaces. Aunque la refactorización será a nivel de código, se presenta el ejemplo a nivel de diseño para su mejor comprensión.

Ejemplo del Problema de Dependencia de Interfaces Para que este problema quede más claro, se ilustrará con una parte de un M A 0 0 del dominio de la estadística, mostrándose su diagrama de clases bajo el estándar UML (Unified Modeling Language) en la Figura 2.

h e d i a n a :double

double GelResultadoO { v-

double GeiResultadoO (

wid Calcula0 (

wid Ordena0 { I / Algoritmo de Ordenacidn

Mid CaiailaO ( I/ Ngoritmo EsladlSüCO Correspondiente

mid Ordena() (

Figura 2. Parte del M A 0 0 de Estadística con Tres Operaciones

Este M A 0 0 proporciona algunas funciones para cálculo estadístico, utilizando una lista (LZ) doblemente ligada para almacenar la serie de números sobre los que operan las funciones. La funcionalidad total que tiene el M A 0 0 completo es el cálculo de medidas de tendencia central, dispersiones, distribuciones, regresiones y correlaciones, y como auxiliares se tienen ordenaciones de datos y solución de sistemas de ecuaciones lineales.

16

Page 39: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capitulo 2. Antecedentes

La parte del MAOOlque se muestra en la Figura 2 tiene las operaciones de media aritmética y mediana, y como auxiliar se tiene una ordenación por burbuja. La media aritmética, implementada en CMediaAri, consiste en la suma de los elementos de la lista dividida entre el total de elementos; la mediana, implementada en CMediana, consiste en el elemento central de la lista ordenada de datos, de ahí la necesidad del algoritmo de ordenación, implementado len CBubble.

Para llamar a la funcionalidad del MAOO, el cliente CContexto utiliza las interfaces de la clase CSIrategy, GeiResultado( ), Ordena( ) y Calcula( ), que se conectan con las especiaiizLciones.

Debido a la naturaleza del MAOO, CBubble implementa a Calcula() sin código y a GetResultado() con có&go nulo (sólo para cumplir con el valor de retorno), y tanto CMediaAri como CMediaha implementan a Ordena( ) también sin código, como se muestra en la Figura 2. Aquí es donde se tiene el problema de dependencia de interfaces por interfaces que en realidad no se ocupan.

El problema surge ,porque fueron mal planificadas las interfaces, que no son ocupadas por todas las clases concretas, y por cumplir con los requerimientos del compilador se tienen que implementar todas las funciones virtuales puras en las clases concretas, aunque sea vacías o con código nulo.

Si un cliente diferente no necesitara la funcionalidad de cálculo, sino sólo la de ordenación, no será posible separar sólo la parte de ordenación para esa aplicación. Esto es debido a que la clase dBubble tiene una interfaz Calcula() que no tiene razón de existir en ese nuevo contedto.

Si se agregara otra funcionalidad diferente a ordenar y calcular, se tendría que modificar a la clase CStrategv para agregar otra función virtual, a la clase CBubble, CMediaAn‘ y CMediana para agregar la nueva interfaz, y a la nueva clase se le tendrían que poner las tres interfaces existentes. Lo cual viola el principio de Abierto / Cerrado por lo que se pierde flexibilidad para extensiones de funcionalidad.

La propiedad de ieuso del M A 0 0 se ve disminuida por el problema de inmovilidad, es decir, nd se pueden llevar ciertas partes del M A 0 0 de manera independiente hacia otros contextos. La propiedad de extensión se ve disminuida por el problema de rigidez, es dkcir, no se puede extender la funcionalidad del M A 0 0 sin modificarlo, y, por supuesdo, esto no es correcto ni deseable en cualquier MAOO, cuyo objetivo ideal es precisamente facilitar el reuso y la extensión.

El problema resulta grave en el M A 0 0 completo, ya que se tienen demasiadas funciones que no se ocup$n y esto puede confundir a cualquier usuario del MAOO. Como se puede ver, este M A 0 0 es bastante completo y ha requerido mucha inversión de tiempo y esfuerzo, y se busca entonces una manera de mejorar su diseño de manera automática.

Solución del Problema 1 Para resolver este p r o b l h a se creó un algoritmo denominado ‘Separación de Interfaces’, basado en el drincipio de diseño orientado a objetos del mismo nombre. Este principio tiene como objetivo el evitar que los clientes dependan de interfaces que en realidad no ocupan [Maft96], entendiendo por cliente a cualquier sistema que utiliza el MAOO.

El método de refactorización propuesto para separar interfaces se’ basa en dos patrones de diseño propueStos por Gamma et al [Gamm95], denominados ‘Strategy’ y

I . .

17

Page 40: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 2. Antecedentes

‘Template Method’. De estos patrones se utiliza sólo su estructura, ya que la intención de ellos no es resolver el problema de dependencia de interfaces, pero se pueden adaptar para que lo hagan.

La refactorización del M A 0 0 consiste en establecer interfaces con nombres genéricos, que se van especializando en las clases derivadas. Es decir, se sustituyen las diferentes interfaces afines por una sola. Esta interfaz genérica tendrá su implementación en clases intermedias nuevas.

Se crean clases intermedias entre la clase base abstracta y las clases derivadas para mostrar las diferentes estrategias a seguir. Cada estrategia se considera que es una especialización del MAOO. Estas clases intermedias también deberían tener nombres genéricos y son especificados por el experto del dominio, usuario de la herramienta de refactorización.

Cada clase intermedia declara a una de las interfaces originales, y esta clase debe servir como clase base de las clases derivadas originales que si ocupan la interfaz.

La interfaz genérica es implementada como un método de plantilla en las clases intermedias. La implementación de este método de plantilla sólo es una llamada hacia la interfaz de cada una de las estrategias o especializaciones, y esta interfaz ya se encuentra implementada por las clases concretas derivadas de las clases intermedias.

Como resultado, cada clase derivada tiene que implementar a una soia y única interfaz, eliminando las interfaces que no se ocupan. Así el M A 0 0 resultante se podrá extender sin modificar nada.

Los beneficios principales que se obtienen con esta refactorización es que los programas que eran rígidos y frágiles por depender de interfaces que no ocupan ahora son robustos y su mantenimiento es más fácil. Asimismo, se consigue que éstos sean más reusables.

Como resultado de la refactorización, se obtienen MAOO’s que no requieren de modificaciones cuando se quiera agregar nueva funcionalidad, respetando así el principio de Abierto / Cerrado, y las nuevas clases sólo declararán interfaces que ocupan, respetando así el principio de Separación de Interfaces del diseño orientado a objetos.

2.4. Objetivo El objetivo general de esta tesis es instrumentar un mecanismo basado en patrones de diseño, que permita refactorizar la arquitectura de clases de MAOO’s escritos en lenguaje de programación C++ que presentan el problema de dependencia de interfaces.

Para lograr este objetivo el M A 0 0 original será refactorizado para evitar que los clientes se vean forzados a depender de interfaces que en realidad no utilizan, separando las interfaces que necesita cada uno de estos clientes de tal manera que se obtengan clases genéricas con mayor nivel de reuso.

Como objetivos específicos, el método de refactorización debe integrar las reglas sintácticas y semánticas para reconocer el problema de dependencia de interfaces, localizar las clases que intervienen en el problema, generar clases intermedias con interfaces genéricas que solucionen el problema, y finalmente refactorizar el código original, siendo la arquitectura resultante de esta refactorización correspondiente a la de los patrones de diseño ‘Strategy’ y ‘Template Method’. También se debe cuantificar este problema que presentan los MAOO’s, diseñando para este objetivo una métrica.

18

Page 41: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

2.5. Límites y Alcances del Para resolver el problema

que sea siempre tiene que ‘ser decidida, aceptada y controlada por el administrador del MAOO.

Estudio de dependencia de interfaces se creó una herramienta de

Adicionalmente la derramienta tiene una interfaz genérica que permite que otras herramientas de refactorización sean agregadas, usando la extensión ya que se emplearon las técnicas de programación orientada a objetos para dicha interfaz, empleando patrones de diseño. En este momento, en el sistema se encuentran integrados tres métodos de refactorizdción del S E .

La herramienta c d n t a con limitaciones, las cuales pueden ser consideradas como trabajos futuros. Primeramente, la refactorización que se lleva a cabo es a nivel de código y dicho código debe estar en el lenguaje C++ con el enfoque orientado a objetos. También este código debk estar libre de errores de implementación, ya que de lo contrario no funciona el código refactorizado, como lo marca los principios de la refactorización [Opdy92]. ’

Existen también limitantes en cuanto al análisis realizado con JavaCC, ya que la gramática empleada está aún incompleta y sigue en desarrollo [Visw96]. La refactorización llevada a cabo por la herramienta sólo resuelve el problema de dependencia de interfaces, en donde los clientes son forzados a depender de interfaces que no utilizan; otro tipo de problemas de diseño, estructura o codificación que presenten los MAOO’s no serán resueltos, ya que existen o existirán otras herramientas del SR2 que se encarguen de esos problemas.

I.

19

Page 42: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

CapítUlO 3. Marco Teórico

Capitulo 3) MARCO TEÓRICO

3.1. Marco de Aplicaciones Orientado a Objetos (MAOO) El reuso se define como “cualquier procedimiento que produce o ayuda a producir un sistema mediante el nuevo uso de algún elemento procedente de un esfuerzo de desarrollo anterior” [Free87]. Con esto se quiere decir que se crea un nuevo sistema de software utilizando componentes de software ya existentes y que sólo se les añade nueva funcionalidad.

Un componente de software reusable es algo que se creó con la intención de ser reusado, siguiendo un diseño y estructura que permita el uso del componente en varios contextos sin que tenga que ser modificado. Estos componentes tienen diferentes niveles de abstracción, que pueden ser desde una especificación de requisitos hasta una biblioteca de funciones o un M A 0 0 que enfatiza el reuso de código y del diseño [Garc97].

Uno de los objetivos principales de la Ingeniería de Software es el reuso, esperando que no sólo se llegue al reuso de componentes completos de código, sino que se llegue al nivel de poder reusar el diseño de sistemas, de tal manera que se puedan

20

Page 43: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

CENTRO DE INFORMAClON SEP CENIDET

21

Page 44: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capitulo 3. Marco Teórico

base abstractas, Ya que ellas tienen muy poco código que heredar o incluso ninguno, sino que sólo ofrecen interfaces.

Composición de Objetos. Es una alternativa a la herencia. Con ella se consigue nueva funcionalidad ensamblando objetos para obtener una funcionalidad más compleja. La composición de objetos requiere que los objetos que están siendo compuestos tengan interfaces bien definidas. AI reuso por composición se le conoce como “reuso de caja negra”, debido a que los detalles internos de los objetos no son visibles.

La composición es definida de manera dinámica (tiempo de ejecución) a través de objetos que tienen referencias a otros objetos. La composición requiere que los objetos respeten cada una de las interfaces de otros objetos, lo que lleva a que se tengan que diseñar cuidadosamente las interfaces, para que sirvan para conectar al objeto con múltiples objetos.

Los diseños por lo general son más simples y reusables si dependen más de la composición de objetos que de la herencia. Debido a esto, muchos patrones de diseño fomentan el uso de composición.

Con la herencia y la composición se pueden crear dos tipos principales de componentes reusables orientados a objetos: las jerarquías de herencia y los MAOO’s basados en dominios de aplicaciones [Garc97].

Jerarquías de Herencia. Son un conjunto de clases asociadas por la herencia de implementacionec, de interfaz y/o de clase, donde existen clases base o abstractas y clases derivadas o subclases. Una clase abstracta tiene como objetivo ser una plantilla para subclases más específicas, y por lo general no tienen instancias y no están completamente definidas, ya que les falta la implementación de métodos que será realizada en las subclases, es decir, que las clases abstractas tienen métodos o funciones virtuales, o funciones virtuales puras (interfaces).

La jerarquía de herencia presenta el problema de dependencias entre las subclases con sus clases base, lo que las hace poco reusables, presentan el problema de romper el encapsulamiento de datos y aumentan su complejidad.

Marcos de Aplicaciones Orientados a Objetos Ó Frameworks. Son un conjunto de clases en colaboración que incorporan un diseño genérico y pueden ser adaptados a problemas específicos. Estos MAOO’s están dirigidos a unidades de negocios y/o dominios en particular, de forma que las clases del M A 0 0 no pueden salir de contextos del ámbito de su dominio. Los MAOO’s enfatizan el reuso del diseño o las arquitecturas que dan solución a problemas recurrentes del dominio de aplicaciones. Un M A 0 0 debe dar facilidades para que se extienda su funcionalidad, ya que un dominio siempre está en constante maduración y se desea que los MAOO’s, mientras vayan evolucionando, lo cubran por completo [Sant02].

La instanciación de un M A 0 0 es el ensamble de los objetos necesarios para solucionar un problema en particular; dichos objetos deben estar configurados de tal manera que trabajen juntos para solucionar el problema. Un M A 0 0 debe ocultar las partes de diseño que son comunes a todas las instancias y dejar accesibles las partes que deben ser especializadas. AI reusar un M A 0 0 sólo se deben realizar dos cosas: definir las nuevas clases que se necesitan y configurar un conjunto de objetos existentes.

Los MAOO’s son generalmente aplicaciones como interfaces de usuario, o ambientes de trabajo multimedia.

. . . . , , * :*,s-- 4 - : : , t l

22

Page 45: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Los MAOO’s traen extensión y la inversión de

23

múltiples beneficios, como son: la modularidad, el reuso, la control [Sant02].

Page 46: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 3. Marco Teórico

y por lo tanto no reusable. Por eso el principio nos dice que cuando se cambien los requisitos o se agreguen nuevos requisitos, se extiende el comportamiento de los módulos añadiendo nuevo código mediante herencia, pero nunca se cambia el código que ya existe y se sabe que funciona [Garc97].

Se dice que un sistema es rígido porque cada cambio afecta a muchos otras partes del sistema, es frágil porque cuando se efectúan cambios, se ocasionan fallas en partes inesperadas del sistema, y es difícil su reuso en otras aplicaciones debido a que los módulos del sistema no pueden ser fácilmente desintegrados de la aplicación actual [Sant02].

Para lograr el objetivo del Principio de Abierto / Cerrado se utiliza la abstracción, ya que se crean abstracciones o clases base que son fijas y representan un grupo ilimitado de posibles comportamientos, y estos comportamientos se dan gracias a la herencia con clases derivadas. De esta manera al reusar las clases base se cierra el código a modificaciones y se extiende el código con nuevas clases derivadas [Garc97].

El Principio de Separación de Interfaces también sirve para realizar buenos diseños de software, evitando clases con interfaces grandes, io cual arriesga a que estas interfaces no estén cohesionadas [Garc97].

Con este principio lo que se trata es que estas interfaces sean separadas en grupos de funciones miembro, donde cada grupo sirve a un conjunto de clientes o clases derivadas diferentes.

El principio enuncia: “Los clientes no deben ser forzados a depender de interfaces que no utilizan” [Mart96].

Este principio es importante ya que cuando los clientes de un MAOO, es decir, programas que usan ai MAOO, se ven forzados a depender de interfaces que no utilizan, éstos se ven afectados por los cambios de dichas interfaces o la adición de nuevas interfaces [Garc97].

Aunado a esto se tiene el problema que cuando se quiere extender el comportamiento de una clase que es dependiente de otras, se tienen que agregar interfaces a las demás clases, viéndose en la necesidad de modificar el código existente, violando el principio de abierto / cerrado que se explicó antes. Como consecuencia, las clases y la arquitectura que las contiene, no son reusables.

De aquí se desprende que el objetivo de este principio, así como el de la tesis, es evitar este tipo de acoplamientos o dependencias, separando las interfaces donde sea posible.

3.3. Refactorización La refactorización es aquel proceso cuyo objetivo es modificar la arquitectura de clases de un sistema, mas no es modificar la funcionalidad del mismo. Para asegurarse que esto no ocurra, una refactorización siempre cuenta con precondiciones y poscondiciones que se deben de cumplir antes y después de aplicar una transformación. Por tanto, la refactorización no ayuda a un sistema actual sino a sistemas futuros que se extiendan del sistema actual [Opdy92].

Las refactorizaciones soportan el diseño y la evolución del software, reestructurando un programa de una manera que permite que otros cambios sean realizados de una manera más fácil. Los cambios más complicados pueden hacerse usando varias refactorizaciones y extensiones [Opdy92].

24

Page 47: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

I Capítulo 3. Marco Teórico

i Una herramienta que ofrece refactorización automatizada debe garantizar que sus operaciones preservan el comportamiento del programa. Una de las razones porque los programas no son refactorizados es debido a que al hacer un cambio se corre el riesgo de introducir errbres al programa. Por eso es importante respetar las precondiciones y poscondikiones de una refactorización, para saber si se va a afectar el comportamiento del programa [Opdy92].

Una refactorización que puede aplicarse sin peligro a introducir errores no necesariamente mejora elm diseño de un MAOO. Si se aplican refactorizaciones de manera arbitraria, es más p 4 obable que se empeore el diseño, aún cuando se mantenga el comportamiento [Opdy92]!

Una refactorización mejora el diseño si las unidades de código resultante corresponden a abstracciones significativas que hacen más fácil refinar o extender un MAOO. La aplicación ylel diseñador son los que deciden que abstracciones son significativas. Esto impliFa que la tarea de refactorización, especialmente las más complejas, requieren algo de interacción con el diseñador [Opdy92].

Una herramienta de refactorización debe ayudar al diseñador ofreciéndole las refactorizaciones adecuadis a un problema, y asegurando que cada refactorización será

I I

final. Por tanto, en ese sentido, la

son muy simples, como cambiar el nombre de una complejas y dependen de un lenguaje en particular; y

están compuestas por refactorizaciones simples, e

automatizada [Opdy92]. Algunas

variable o

involucran el uso de los patrones de diseño orientados a objetos. De este último tipo es la refactorización que se presenta en esta tesis, utilizando patrones de diseño y está enfocada a MAOO’s escritos en el lenguaje de programación C++.

Dependiendo de la komplejidad, las refactorizaciones se pueden hacer de manera automática o semiautomá’tica, pero lo que deben de hacer automáticamente es la

administrador del MAOd o experto del dominio la decisión de realizar o no la refactorización. En las refhctorizaciones complejas muchas veces se requerirá de algo de interacción con el usuaho, como ocurre en nuestro caso, en donde el usuario tiene que tomar decisiones en cdanto a ciertos nombres de funciones y clases que se agregan a la arquitectura original.

En esta tesis se deshrrolla un método de refactorización y una herramienta que implemente dicho método/ para refactorizar y mejorar los diseños de MAOO’s que resulten problemáticos debido a la dependencia entre clases por interfaces no utilizadas. La herramienta sólo tiene que interactuar lo mínimo necesario con el usuario para hacer la refactorización por la Separación de Interfaces.

validación de las precondiciones I y poscondiciones. Es responsabilidad del

I

3.4. Métricas Orientadas a Objetos La necesidad de medir es evidente en la mayoría de las actividades técnicas o científicas. Sin embargo, no interesa sólo contar con medidas sino también saber si dichas medidas son válidas. Para ello se toma la definición de medición como el “proceso por el cual se asiknan números o símbolos a atributos de entidades del mundo real de tal forma que los ddscriba de acuerdo con reglas claramente definidas” [Fent97]. La validez de la medición en cualquier disciplina técnica o científica se basa en el respeto a los principios de la teoria general de la medición. Esta idea es análoga a lo que

I

I

25

Page 48: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 3. Marco Teórico

se hace en matemáticas donde se definen una serie de axiomas básicos y, a partir de ellos, se van estableciendo nuevas conclusiones [Caie02].

El fundamento de la teoría de la medición consiste en que toda medición debe asegurar una adecuada representación del atributo real medido mediante los símbolos o números asignados. Una representación por medición de un atributo de una entidad es adecuada si es coherente con la idea conceptual que sobre dicho atributo es comúnmente aceptada por los expertos [Caie02].

Así, los datos obtenidos como medidas deben representar los atributos de las entidades reales que se pretende caracterizar y el manejo de dichos datos debe preservar las relaciones que existen entre dichas entidades. Para establecer medidas se debe partir de la observación del mundo real o dominio. Se debe identificar cuáles son las entidades que se quieren medir (por ejemplo, código) y definir qué atributo se desea caracterizar (por ejemplo, longitud de código). Además, es importante identificar las relaciones empíricas que se pueden establecer entre las entidades reales en relación con el atributo que interesa. Estas relaciones pueden ser simples comparaciones que establecen un orden (por ejemplo, “código del programa X más largo que el del programa Y”) ó relaciones de otros tipos, ni siquiera binarias (por ejemplo, relación unaria: “el código de X es largo”). Se puede hablar entonces del dominio como de un sistema de relaciones empíricas. La medición asigna un valor a cada entidad para caracterizar su atributo (por ejemplo, al programa X se le asigna un valor de longitud en líneas de código de 305) y debe establecer también que relación entre valores se corresponde con cada relación empírica (por ejemplo, para la relación de orden “código más largo que” se puede asignar la relación numérica). Lo importante es que la medición que se establece no resulte inconsistente con las relaciones observadas en el mundo real. Así, es necesario que si se observa que el código de X es más largo que el de Y (según la idea aceptada de longitud de código) se debe comprobar que el valor de longitud de X (por ejemplo, 305) es mayor (>) que el asignado a Y (por ejemplo, 245) [Cale02].

Hay que señalar que no siempre las ideas sobre los atributos o sobre las relaciones empíricas están tan claras o no hay un consenso sobre ellas. Se puede comenzar por simples valoraciones subjetivas, que no constituyen medidas desde el punto de vista de la teoría de la medición pero que pueden ser analizadas para mejorar la comprensión sobre el mundo real. Es posible que tras acumular datos de este tipo se pueda llegar a definir una medida formal [Cale02].

Por otra parte, también se podrían establecer múltiples representaciones para un mismo sistema de relaciones empíricas. En general, cuantas más relaciones empíricas estén identificadas, más se restringe la variedad de representaciones posible. Una asignación que se establece entre mundo real y valores de medida se suele denominar escala de medición. Existen cinco tipos principales de escalas de medición [Cale02]:

Nominal: simplemente se clasifica cada entidad (por ejemplo, código) en grupos (por ejemplo, lenguaje COBOL, Basic, C, Java, etc.). Ordinal: se clasifican las entidades en grupos pero estableciendo un orden (por ejemplo, fallos de software: parada de sistema, mal funcionamiento, leve o cosmético). De intervalo: establece un orden y además informa sobre la diferencia existente entre un valor y otro consecutivo en orden es siempre la misma (por ejemplo, tiempo empleado: días transcurridos desde el comienzo del proyecto).

26

Page 49: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

LZ

Page 50: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 3. Marco Teórico

2. Métricas de Árbol: Estas métricas consideran el número de clases, profundidad de árbol, y numero de funciones miembro, número de variables, polimorfismo y herencia múltiple. La métrica diseñada en esta tesis se encuentra en esta categoría.

3. Métricas de Clase: Estas métricas consideran el número de subclases, profundidad de clase, LOC (líneas de código) de una clase, número de funciones miembro de una clase, polimorfismo, herencia múltiple, funciones y operaciones amigas (friend) y operandos.

Se han propuesto varios marcos para validar formalmente a una métrica, algunos están basados en propiedades y otros están basados en la teoría de la medición. El primer tipo es más simple que el segundo debido a que la teoría de la medición es puramente matemática, que es un área no siempre comprendida y dominada por los programadores y desarrolladores de software.

Para proveer de bases a la métrica propuesta, llamada V-DINO, se tomará un marco de cada tipo. El marco basado en propiedades es el propuesto por Briand et al [Bria96]. El marco basado en la teoría de la medición es el propuesto por Zuse en [Zuse95] y [Zuse98].

Los marcos basados en propiedades se limitan a suministrar condiciones necesarias pero no suficientes para los conceptos que definen, y sirven para clasificar a las métricas por tipos [Cale02].

Una de las aportaciones más importantes para aplicar la teoría de la medición es la planteada en [Bria96] como medición basada en propiedades. En este trabajo, se presentan las relaciones empíricas que pueden observarse en los atributos longitud, tamaño, complejidad, acoplamiento y cohesión de un sistema. Los axiomas presentados son los que deberían preservar las métricas que pretendan representar estos atributos de, un sistema.

V-DIN0 se clasifica como una métrica de cohesión en el marco de Briand et al [Bria96]. La demostración de esto se encuentra en el Anexo A.

El concepto de cohesión se refiere a la estrechez con la que están agrupadas las propiedades relacionadas de programas dentro de módulos o sistemas. Se asume que mientras más capacidad tenga el programador de encapsular propiedades relacionadas de un programa, el sistema será más confiable y mantenible [Fent94].

La cohesión debe ser no negativa y, más importante, debe estar normalizada para que la medida sea independiente del tamaño del sistema.

Los marcos basados en la teoría de la medición tienen como objetivo obtener la escala matemática a la que pertenece una métrica, y por tanto sus transformaciones admisibles, estadísticos y pruebas estadísticas aplicables [Cale02].

La métrica V-DMO cumple las condiciones de transitividad y compleción para estar dentro de la escala ordinal del marco propuesto por Zuse [Zuse98]. La demostración se encuentra en el Anexo B.

La escala ordinal es única sólo de acuerdo al orden. Las transformaciones admisibles son las funciones incrementales. Los estadísticos significativos son estadísticos de clasificación por orden y estadísticos no paramétricos. Las unidades y la escala ordinal no son compatibles. La intención de las unidades es determinar una diferencia entre los números y los objetos considerados. Ya que la escala ordinal sólo considera clasificación por orden, no se pueden asignar unidades.

28

Page 51: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 3. Marco Teórico

Otra de las carac erísticas de la métrica propuesta es estar normalizada. La muy usado con la finalidad de obtener valores entre O y 1. normalización es un

Algunas de las consecuehcias de esta calibración en una métrica es que estadísticos, como la media aritmética! no tienen significado. Pero dado nuestro objetivo de medir el grado de dependencia debido a interfaces no ocupadas, estos estadísticos no se necesitan, y sí se puede adignar un significado intuitivo a los números entre O y 1.

3.5. Patrones de Diseña Para la solución del problema resuelto por esta tesis se utilizaron los patrones de diseño, que engloban un conjuntd de componentes que tienen un comportamiento conocido con mejores estructuras, usaddo para ello la experiencia de expertos y las prácticas de diseño [ChuWOO].

A los patrones de diseño se les considera como una herramienta para análisis y diseño que prevé el uso a hturo de los componentes de software.

Con los patrones dk diseño se logra una mejor comunicación con el personal que trabaja en un diseño, ya ’ ue incrementan el reuso y productividad en el desarrollo de software. Con patrones d 1 diseño es posible hacer reingeniería a sistemas legados, que serían costosos de manteher en su estructura y diseño original, y con la reingeniería basada en patrones de diskño se obtienen nuevos sistemas con buen diseño y estructura que son más fáciles se codprender, mantener y reusar [ChuWOO].

Un patrón de dise-o nombra, abstrae, e identifica los aspectos clave de una estructura común de diseno que la hace útil para crear un diseño orientado a objetos reusable. Estos patrones identifican las clases participantes y sus instancias, sus funciones y colaboraciones, y la distribución de sus responsabilidades. Cada patrón de diseño está especializado Ln un problema particular de diseño orientado a objetos, por lo tanto, no todos los patrdnes de diseño se pueden utilizar en todos los casos, y se debe observar cuándo se pueden aplicar, y qué consecuencias traerá su uso [SantOZ].

Existen muchos patrones de diseño, organizados en catálogos de patrones de diseño. Cada patrón tienk un objetivo específico, y al utilizarlos se adquieren sus ventajas y desventajas. Ed esta tesis se utilizan cuatro patrones de diseño del catálogo de Gamma, llamados ‘Strakegy’, ‘Template Method’, ‘Command’ y ‘Singleton’.

Se utiliza la estructha de los patrones de diseño ‘Strategy’ y ‘Template Method’ para realizar el método de refactorización, esto es porque la intención de estos patrones es diferente al uso que se les da en el método. Los patrones ‘Command’ y ‘Singleton’ fueron usados para realizar la interfaz de la herramienta.

Para describir un patrón de diseño, se utiliza la forma ‘Alexandriana’, también referida como ‘GOF’ o f o h a ‘canónica’ [Sant02], donde:

P

I

referirse al patrón, y el conocimiento

las metas y objetivos que quiere alcanzar encontrada, donde por lo general, los

bajo las cuales el problema y su solución la solución, y con esto se puede

no a cierto problema. las restricciones relevantes y cómo y con las metas que se desean.

y ia estructura que

29

Page 52: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 3. Marco Teórico

5. La solución representa a las reglas de relación tanto estáticas como dinámicas, que describen cómo obtener el resultado deseado. La descripción puede utilizar figuras y diagramas para identificar la estructura del patrón, sus participantes y sus colaboraciones para mostrar cómo se resuelve el problema. La estructura estática indica la forma y la organización del patrón, pero con frecuencia es el comportamiento dinámico lo que hace que el patrón viva.

6 . Los ejemplos describen las condiciones posteriores al uso del patrón y los efectos laterales, buenos y malos, del patrón.

7. El razonamiento nos dice cómo trabaja el patrón actualmente y por qué es bueno. A diferencia de la solución, el razonamiento proporciona el conocimiento de la naturaleza interna de la estructura, y los mecanismos clave que están bajo la superficie del sistema.

8. Los patrones relacionados muestran las relaciones estáticas y dinámicas entre un patrón y otros. Existen patrones que comparten las fuerzas, otros comparten los contextos iniciales y finales, unos dan una solución alterna al mismo problema, incluso algunos pueden aplicarse simultáneamente.

Patrón de Diseño ‘Strategy’ [Gamm95] Intención: Define una familia de algoritmos, encapsula cada uno y los hace intercambiables. ‘Strategy’ deja que los algoritmos varíen independientemente de los clientes que los utilizan. Problemática: Si los clientes potencialmente, tienen algoritmos embebidos en ellos, es difícil reusar estos algoritmos, intercambiar los algoritmos, desacoplar diferentes capas de funcionalidad, y variar la elección de la política a seguir en tiempo de ejecución. Estos mecanismos de políticas embebidas rutinariamente se manifiestan a sí mismos como expresiones condicionales múltiples. Fuerzas:

Un programa tiene que proporcionar múltiples variaciones de un algoritmo. Se puede encapsular las variaciones del comportamiento en clases separadas que provean de una forma consistente de acceder a los comportamientos. Poner estos comportamientos en clases separadas, significa que las clases o clientes que utilicen estos comportamientos no necesitan saber nada acerca de sus implantaciones. Dando a estas clases una superclase común, o interfaz, permitirá a las clases o clientes que los utilicen no preocuparse de cómo seleccionar un comportamiento o de cuál comportamiento es seleccionado.

Estructura: Cuenta con una clase base abstracta, Estrategia, que tiene una interfaz genérica, Algortimolnterfaz, que es implementada por cada clase EstrategiaConcretaX. Un objeto strategy de tipo Estrategia es agregado al cliente Contexto. Ver Figura 3 .

30

Page 53: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 3. Marco Teórico

Para implantar las subclases implantar

Estrategia +strategy Contexto

partes invariantes de un algoritmo una vez, y dejar a las el comportamiento que puede variar.

31

Page 54: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 3. Marco Teórico

Patrón de Diseño ‘Command’ [Gamm95] Intención; Encapsula un mensaje como un objeto, con lo que permite parametrizar a los clientes, gestionar colas o registro de mensajes y deshacer operaciones.

Problemáticat En ocasiones es necesario enviar peticiones a objetos sin saber nada acerca de la operación solicitada ó del receptor de la petición. Por ejemplo, las herramientas de desarrollo de interfaces de usuario incluyen objetos como botones y menús que llevan a cabo una solicitud en respuesta a entradas del usuario. Pero la herramienta no puede implementar la petición explícitamente en el botón o menú, porque sólo las aplicaciones que usen la herramienta de desarrollo saben que debe realizarse en cada objeto. ‘Command’ permite que los objetos de la herramienta de desarrollo hagan peticiones a objetos no especificados de la aplicación convirtiendo la propia petición en un objeto. Este objeto puede ser almacenado y transportado como cualquier otro objeto.

Casos de Aplicación: Para parametrizar objetos por una acción a realizar. Esta parametrización se hace con funciones “callback”, esto es, funciones que están registradas en algún lado para ser ejecutadas momentos después. ‘Command’ es el reemplazo orientado a objetos de las funciones “callback”. Para especificar, poner en cola y ejecutar peticiones en tiempos diferentes. Un ‘Command’ puede tener un tiempo de vida independiente de la petición original. Para soportar deshacer. La operación Ejecutar( ) del ‘Command’ puede almacenar su estado para revertir sus efectos en el comando. Los comandos ejecutados se pueden almacenar en un historial y de ahí deshacerlos. Para soportar caídas del sistema. Si se agregan las operaciones de almacenar y cargar, se puede tener una bitácora de cambios. Ante una caída del sistema se recuperan y ejecutan todos los comandos. Para estructurar un sistema a base de operaciones de alto nivel llevadas a cabo por operaciones primitivas. Esta estructura es común en sistemas de información que soportan transacciones.

Estructura; La clase Command declara la interfaz Ejecutar( ) para ejecutar la operación; la clase CommandConcreto vincula un objeto Receptor y una operación e implementa el método Ejecutar() que invoca dicha operación; la clase Cliente crea un objeto de la clase CommandConcreto y establece su receptor; la clase Invocador solicita que se ejecute la orden y cualquier clase Receptor se encarga de llevar a cabo las operaciones. Ver Figura 5.

32

Page 55: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

CaDítulo 3. Marco Teórico

I 1 n \ \

Figura 5. Estructura del Patrón de Diseño ‘Command’

Patrón de Diseño ‘Singleton’ [Garnrn95] intención: Asegura que sólo exista una instancia de una determinada clase y proporciona la forma de acceder a ella.

Problemática: Es importante para algunas clases tener exactamente una instancia y tener fácil acceso a ella. Por ejemplo, aunque puede haber muchas impresoras en un sistema, sólo puede haber una cola de impresión. Una variable global hace a un objeto accesible, pero no previene de hacer múltiples instancias. Una mejor solución es hacer que la propia clase sea responsable de llevar el control de su instancia Única. La clase puede asegurar que no se crearán más instancias, interceptando peticiones para crear nuevos objetos, y puede proveer una forma de acceder a la instancia.

Casos de Aplicación: Se utiliza cuando debe de existir sólo una instancia de una clase, y debe estar accesible a los clientes desde un punto conocido de acceso. Cuando la instancia única debería ser extensible por subclases, y los clientes deberían poder usar una instancia extendida sin modificar su código.

Estructura: La clase que necesita una única instancia, Singleton, declara un método de clase, InstanciarO, que permite acceder a la Única instancia, instnnciaUnica, y puede ser el responsable de crear dicha instancia. Ver Figura 6 .

<<statio> instanciaUnica

return instanciaunica; ---n *<<staüo> instanciar0 *OperacionSingleton() *ObtenerDatosSingleton()

Figura 6. Estructura del Patrón de Diseño ‘Singleton’

33

Page 56: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 4. Método de Solución

Capitulo 4) &TODO DE SOLUCI~N

4.1. Refactorización por el Método de Separación de Interfaces La refactorización del M A 0 0 consiste en establecer interfaces con nombres genéricos, que se van especializando en las clases derivadas. Es decir, se sustituyen las diferentes interfaces por una sola.

Esta interfaz genérica juega el papel de la interfaz genérica AZgoritmoZnterfaz() del patrón de diseño ‘Strategy’, que tendrá su implementación en nuevas clases intermedias. La clase base original es la clase Estrategia del patrón.

Siguiendo el patrón ‘Strategy’ de la Figura 3, se crearán clases intermedias entre la clase base abstracta y las clases derivadas para mostrar las diferentes estrategias a seguir. Cada estrategia se considera que es una especialización del MAOO. Estas clases intermedias también tienen nombres genéricos que pueden ser especificados por el experto del dominio y representan las clases EstraíegiaConcretaX del patrón ‘Strategy’.

Cada clase intermedia declara a una de las interfaces originales, y esta clase debe servir como clase base de las clases derivadas originales que si ocupan la interfaz.

Aquí es donde entra el patrón ‘Template Method’, ya que la interfaz genérica es implemcntada como u n método de plantilla en las clases intermedias. La

34

Page 57: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

mntexto I +SV

I -

/I Regresa Variable Miembm return o:

CsIraleQy

*-zabslract.rGetRer”lBa~) k -bshacb> plgon’miohteitai()

mid Calcula0 ( m4d Calcula() ( 1; /I Algodtmo Esladklico Cmrerpmdienle I A!gonlmo de Ordenacidn 1 Figura 7. M A 0 0 Refactorizado Usando el Método de Separación de Interfaces

Nótese que la clase CStrategy sólo tiene una interfaz genérica AlgoritmoInterfaz(), se han creado las clases intermedias CAlgorlLl y CAlgorlL2 para indicar las estrategias de Ordenación y Cálculos, en donde cada una implementa AlgoritmoInterfaz() con una llamada hacia su propia función de interfaz.

Las clases derivadas originales CBubble, CMediaAri y CMediana sólo implementan la interfaz que ocupan. CBubble implementa a Ordena(), CMediaAri y CMediana implementan a Calcula(). Todas siguen implementando a GetResultado().

WgarlL1

*-Mwalrr p l g O d b n 0 l ” ~ ~ q ) *4mal= csiaila()

35

CAlgalU

*<*mal>> pigodmioinasr$~) *whJalr> Ordena()

Page 58: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

CapítUlo 4. Método de Solución

De acuerdo a la estructura de los patrones, CStrategy es la clase Estrategia del ‘Strategy’, AlgoritmoInterfaz( ) es la interfaz genérica del ‘Strategy’ y la interfaz TemplateMethod( ) del ‘Template Method’, CAlgorlLJ y CAlgorlL2 son las clases derivadas EstrategiaConcretaX del ‘Strategy’ y las clases base ClaseConcreta del ‘Template Method’, CMediaAri, CMediana y CBubble son las clases derivadas CIaseConcretaX del ‘Template Method’, y Ordena() y Calcula() son las interfaces del ‘Template Method’ OperacionPrimitivaX().

El M A 0 0 en total tiene cuatro interfaces problemáticas y se requiere de tres clases intermedias para resolver el problema. Esta transformación del marco estadístico se puede ver en el capítulo de “Evaluación Experimental”. Como se observará, cuando este método de refactorización se aplique al M A 0 0 completo de estadística, del cual forma parte esta pequeña jerarquía de clases, se eliminarán 58 funciones no utilizadas de 29 clases derivadas, lo cual mejorará considerablemente el diseño del M A 0 0 y reducirá el código del mismo.

Beneficios Obtenidos por la Refactorización Básicamente existen dos beneficios que se logran con la separación de interfaces, uno es la facilidad de reusar parte del M A 0 0 en otras aplicaciones y el segundo es la facilidad de extensión de la funcionalidad del MAOO.

El reuso se logra debido a que las interfaces ya no son dependientes entre sí, por lo que se puede transportar parte del M A 0 0 a otra aplicación sin necesidad de modificar nada, y sin que haya interfaces que obstaculicen esta transportación.

En el ejemplo de la Figura 7 se podría llevar sólo la funcionalidad de ordenamientos a otra aplicación, transportando las clases CSfrategy, CAlgorlL2 y CBubble uniéndolos a otro cliente diferente de CContexto. Se puede notar que separando estas clases no queda ningún rastro de que existiera la interfaz Calcula() y todas las clases que implementan cálculos estadísticos.

La mejora en la cualidad de extensión se logra debido a que cuando se necesita agregar nueva funcionalidad al MAOO, no se requiere modificar nada de lo ya existente.

Si la nueva funcionalidad ocupa las interfaces que ya están definidas, sólo se agrega por herencia las nuevas clases a las clases intermedias. Si la nueva funcionalidad ocupa de una interfaz diferente a las existentes, pero tiene la misma firma que las anteriores, sólo se tiene que agregar una nueva clase intermedia que herede de la clase abstracta, y agregar las nuevas clases con funcionalidad diferente a esa clase intermedia.

Ambos casos se ilustran en la Figura 8, donde se está agregando un nuevo algoritmo de ordenación de datos, Shell, otro cálculo estadístico, desviación media, y la funcionalidad de resolver sistemas de ecuaciones, método de Gauss Jordan.

El nuevo método de ordenación por Shell está implementado en la clase CShell, que hereda de CAlgorlL2, la cual cuenta con la interfaz Ordena(). La desviación media está implementada en la clase CDesvMed, heredando de CAlgorlLI que ofrece la interfaz Calcula(). Para la nueva funcionalidad de resolución de ecuaciones se agrega la clase intermedia CAIgorlMJ que ofrece la interfaz Resuelve() y la clase CGaussJor tiene implementado el algoritmo de resolución.

36

Page 59: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

LE

'P

'E

' Z

' I

I I I I

I

Page 60: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 4. Método de Solución

5.

6 .

7.

8.

9.

la función vacía. En el ejemplo las tres interfaces Calcula( ), Ordena() y GetResultadoO se consideran problemáticas. Se coloca en la clase abstracta una nueva función de interfaz, denominada AlgoritmoZnterfaz( ), y se eliminan de esta clase las interfaces problemáticas originales que pueden ser sustituidas por la nueva interfaz. Se hacen tantas nuevas interfaces como se requieran. En el ejemplo se sustituyen las interfaces Ordena() y Calcula() por AlgoritmoInterfaz(). Para hacer las nuevas interfaces se toman las consideraciones mencionadas en las precondiciones. Se agrupan las clases derivadas originales por las interfaces que implementan. Por cada grupo se crea una clase abstracta intermedia que implementa a la interfaz genérica AlgoritmoInierfaz( ) como un ‘Template Method’. Esta implementación lo que deberá hacer es invocar a la implementación de las interfaces originales de manera adecuada. En cada clase intermedia se coloca la función virtual pura original que sí es implementada por las clases derivadas del grupo. Del ejemplo anterior las funciones Ordena( ) y Calcula( ) serían invocadas desde las nuevas clases intermedias, que denominaremos CAIgorlLl y CAlgorZL2, respectivamente. Se cambia la relación de herencia de las clases derivadas hacia la clase intermedia, que a su vez hereda de la clase abstracta original. También se cambian las directivas “#include” que sean necesarias. Se borran las implementaciones de funciones vacías en cada una de las clases derivadas originales.

10. Para asegurarse que la refactorización no afecte ai MAOO, dentro del código de todo el sistema se buscan las llamadas a las funciones virtuales puras originales, y se cambian por los nombres genéricos nuevos. Esta es la única poscondición del método de Separación de Interfaces.

Cabe aclarar que cuando un M A 0 0 tiene varias clases abstractas, este proceso se sigue para cada una de las clases abstractas de manera independiente, ya que el método sólo afecta a la jerarquía de herencia de esa clase abstracta no al sistema completo. Este algoritmo fue implementado con éxito en la herramienta SR2 Refactoring que será explicada a detalle en el próximo capítulo.

Precondiciones del Algoritmo de Separación de Interfaces Como todo método de refactorización, para ser ejecutado, debe validar ciertas precondiciones para que sea posible y factible la transformación del código fuente y llevar a cabo un rediseño exitoso. Todas las precondiciones son verificadas de manera automática por la herramienta antes de tratar de llevar a cabo la refactorización. Las precondiciones del método de Separación de Interfaces son:

Las interfaces que son seleccionadas para sustituirse por una nueva interfaz deben contar con los mismos parámetros y el mismo valor de retorno. Para que una implementación de una interfaz con un valor de retorno se considere vacia se debe de considerar lo siguiente: La única instrucción que debe haber, si el valor de retorno es de tipo numérico, es “ { return O; }”, si el valor es de tipo boleano, “1 return false; }”, si el valor es de tipo cadena, “ { return “”; }”, y si el valor es referencia a un objeto, “ ( return null; }”. Obviamente, si la

0

38

Page 61: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 4. Método de Solución

función no tiene valor de retorno (void) la función estará libre de implementación de código, es decir, sólo estarán las llaves de apertura y cerradura " { }". Todos los nombres de las clases intermedias que se agregan no deben estar siendo usados por otra clase; la misma condición aplica para los nombres de las interfaces genéricas agregadas. La consideración que se debe hacer para la refactorización es que las implementaciones de las interfaces que se sustituyen deben ser mutuamente excluyentes, es decir, no debe haber una clase derivada que implemente a más de una interfaz.

En el caso del M A 0 0 de la Figura 2 no se puede hacer nada con la interfaz GetResultado() que no es requerida en la clase CBubble, ya que no existe otra interfaz con su misma firma.

Sí se puede sustituir a las interfaces Ordena() y Calcula() por una sola interfaz, ya que ambas funciones tienen la misma firma y son mutuamente excluyentes.

Por mutuamente excluyente se entiende que cuando se agrupen las clases derivadas por las interfaces que implementen, una clase no debe estar en dos grupos, es decir, que no tenga que derivarse de dos clases intermedias. Si en el ejemplo de la Figura 2 se tuviera otra clase derivada, ClaseX, que implementara con código a las interfaces Ordena() y Calcula(), entonces se diría que Ordena() y Calcula() no son excluyentes. En ese caso no se puede aplicar el método de Separación de Interfaces, ya que la interfaz genérica no sabría hacia cual de los dos métodos dirigirse. Este ejemplo de interfaces que no son mutuamente excluyentes se muestra en la Figura 9.

- \- 1

Figura 9. Ejemplo de un M A 0 0 con Interfaces que no son Mutuamente Excluyentes

39

Page 62: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 4. Método de Solución

La clase ClaseX implementa con código a Calcula() y Ordena(), por tanto no son mutuamente excluyentes estas interfaces, y no se pueden sustituir por una sola ya que ambas se necesitan.

Como consecuencias negativas del uso de estos patrones se tiene que se aumenta en uno el nivel de profundidad del árbol de herencia, y también se añaden más llamadas a funciones para llegar a la implementación real. Sin embargo, estas consecuencias no desmeritan los beneficios obtenidos.

4.3. Métrica V-DIN0 (Dependencia por Interfaces que No se Ocupan) Se ha diseñado una métrica orientada a objetos para medir el problema de dependencia de interfaces por contar con interfaces que no se utilizan. Esta métrica entra en la clasificación de “métrica de árbol” en el marco de métricas orientadas a objetos propuesto en [Zuse98] y es una escala de tipo ordinal [Zuse98].

La métrica está basada en otra métrica ya existente, denominada C-NOC (Number Of Children) [Chid94], que cuenta el número de clases derivadas directamente de una clase padre. También está basada en otros conteos de las funciones virtuales puras y de las implementaciones vacías.

Esta métrica debe ser aplicada a cada una de las clases abstractas que se tengan en un MAOO, y no hay una manera para combinar dichos valores, ya que cada árbol de clases se considera independiente. Por clase abstracta entendemos en este contexto que es una clase que tiene una o más funciones virtuales puras y que además tiene una o más clases derivadas que implementan dichas funciones virtuales.

Los elementos que intervienen son el Número de Funciones Virtuales (NFV), el Número de Funciones No Ocupadas (NFNO), y el número de subclases (C-NOC).

NFV: Este número representa a las interfaces declaradas en una clase abstracta. Este mismo número representa al número de interfaces que deben ser implementadas en cada una de las subclases derivadas de la clase abstracta. NFNO: Este número representa a las interfaces no utilizadas en todas las subclases de cierto árbol. Por interfaz no utilizada se entiende una interfaz que tiene código vacío o nulo sólo para cumplir los requerimientos del lenguaje de programación, pero desde el punto de vista lógico no tiene razón de existir porque no significa nada en el contexto del dominio del MAOO. C-NOC: Este número representa el número de subclases inmediatas subordinadas a una clase en la jerarquía de clases. Para este propósito se utiliza la métrica C-NOC (Chidamber - Number of Children) [Chid94]. Es una medida de cuántas subclases van a heredar los métodos de la clase padre.

La métrica se llama V-DIN0 [Dependencia por Interfaces que No se Ocupan) y . . su expresión matemática se muestra en la Ecuación 1 :

NFNO V - DIN0 = C - N O C X N F V

La expresión C-NOC x NFV representa el número total de interfaces en todas las subclases, ya sea que se necesiten o no, y NFNO representa sólo a las interfaces no utilizadas. Debido a lo anterior, la condición NFNO 5 (C-NOC x NFV) siempre será verdadera para cada MAOO, y por tanto, O 5 V-DIN0 5 1.

40

Page 63: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 4. Método de Solución

Esta métrica sólo puede ser usada para clases abstractas que tengan ai menos una clase hija, para que C-NOC # O y NFV# O. Como se mencionó, esta métrica es una métrica de árbol, por lo que el análisis debe ser hecho de forma separada para cada árbol del MAOO. Este árbol debe empezar con una clase base abstracta.

Esta métrica está dentro de la escala ordinal, por lo que sus valores sólo pueden ser comparados, no sumados o usados para una media aritmética. Debido a la normalización, los valores de la métrica no dependen directamente del tamaño del M A 0 0 o de sus árboles. El valor Óptimo es O, que significa que el problema no existe en ese árbol, y 1 es el peor caso (inalcanzable en casos prácticos), lo que significa que la totalidad de interfaces no son necesarias.

Para el M A 0 0 de la Figura 2, se tiene que NFNO = 4, C-NOC = 3 y NFV = 3 para la clase abstracta CStrategy. Por tanto la métrica V-DIN0 = 4 / (3 x 3) = 0.444. Sin embargo, esta jerarquía de clases corresponde a un M A 0 0 más completo que cuenta con NFNO = 71, C-NOC = 29 y NFV = 4, es decir, un valor de V-DIN0 = 71 / (29 x 4) = 0.612.

En el capítulo de “Evaluación Experimental” se muestra éste y otros MAOO’s con el problema de dependencia de interfaces, con su cálculo de la métrica V-DMO.

De acuerdo a los casos de estudio y otras pruebas, se considera que el problema es grave cuando la métrica arroja un valor mayor o igual a 0.5, basándose en el caso más común mostrado a continuación.

El caso más común del problema de dependencia de interfaces se presenta en MAOO’s donde cada clase derivada utiliza una interfaz diferente y todas las otras interfaces no se necesitan. En estos casos C-NOC = NFV y NFNO = (C-NOC x NFV) - NFV. Para estos casos, la métrica V-DINO está definida como se muestra en la ecuación 2.

C-NOC 2 3 4 5 6

(c- NOC x NFV)- NFV - c - NOC -1 V-DINO= - C- NOC x NFV C- NOC

V-DIN0 1/2 = 0.500 213 = 0.666 3/4 = 0.750 415 = 0.800 516 = 0.833

Por tanto, de acuerdo a la ecuación 2, un M A 0 0 con dos clases tiene un valor de V-DIN0 = (2 - 1)/2 = 1/2 = 0.500, con tres clases tiene un valor de V-DIN0 = (3 - I ) I 3 = 2/3 = 0.666, con cuatro clases tiene un valor de V-DIN0 = (4 - 1) / 4 = 3/4 = 0.75, y así sucesivamente.

La Tabla 2 muestra el comportamiento de V-DIN0 en el caso donde cada implementación de interfaz es mutuamente exclusiva en todas las subclases.

Tabla 2: Caso más de Interfaces

41

Page 64: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 4. Método de Solución

Como se puede ver en la Tabla 2, V-DIN0 tiene un valor mayor o igual a 0.500 y nunca alcanzará el valor de 1.

En la métrica no se está considerando el caso de que las implementaciones de las interfaces sean excluyentes. Debido a esto, para tomar la decisión de realizar o no la refactorización se considerarán dos análisis: Primero que V-DIN0 >= 0.5 y segundo que una interfaz a sustituir no esté implementada en alguna clase derivada junto con otra de las interfaces que se van a sustituir, es decir, que sean mutuamente excluyentes, si no lo son, no se puede aplicar el método.

Cuando V-DIN0 < 0.500 no se puede asegurar que el problema se pueda resolver debido a que existen pocas interfaces que no se utilizan y las interfaces pueden no ser mutuamente excluyentes.

Por ejemplo, en el M A 0 0 mostrado en la Figura 9, se tiene que C-NOC = 4, NFV = 3, y NFNO = 4, dando un resultado de V-DIN0 = 4 I(4 x 3) = 0.333. Ya que V- DIN0 < 0.500 se concluye que el M A 0 0 mostrado en la Figura 9 tiene un problema de dependencia de interfaces menos severo que no necesita ser resuelto por el método de Separación de Interfaces. También, no se considera un problema ya que ambas interfaces se necesitan, por tanto, esas interfaces no pueden ser separadas.

La métrica está implementada en la herramienta y es calculada automáticamente generando los datos de la fórmula directamente de la base de datos que contiene el análisis del código fuente de un M A 0 0 cualquiera.

42

Page 65: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

Capitulo 5) DESARROLLO DEL SISTEMA

5.1. Análisis del Sistema A continuación se presenta un extracto del documento de análisis del sistema, modelado con diagramas de casos de uso de UML. El resto del documento se encuentra en el Anexo C.

La Figura 10 muestra el diagrama general de la herramienta, mostrando las opciones que tiene el usuario.

Hay cinco casos de uso principales: Manejar Archivo, Análisis Sintáctico, Métrica, Generar Arquitectura y Generar Código. Los actores son: Usuario, la persona que usa la herramienta; Archivo Original, archivos del M A 0 0 que escoge el usuario y serán refactorizados; Archivo Fuente, posible copia de seguridad de los archivos originales; Archivo Final, los archivos originales modificados usando los métodos de refactorización; y Base de Dalos, para contener el análisis sintáctico y parte de la refactorización.

La Figura 11 muestra el diagrama del caso de uso Manejar Archivo, que debe ser invocado antes de hacer cualquier otra operación.

43

Page 66: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

Principal

’\/ Métrica

k h i w Final Generar didiga

Figura 10. Diagrama de Casos de Uso Principal

rn Manejar Archiw

Figura 11 . Diagrama del Caso de Uso Manejar Archivo

44

Page 67: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. 'Desarrollo del Cisterna

Primero se seleccionan todos los archivos del M A 0 0 que se desea analizar y

La Figura 12 muestra el diagrama del caso de uso Análisis Sintáctico, que puede refactorizar, y opcionalmente se puede crear una copia de seguridad de estos archivos.

ser invocado ya sea desde la pantalla de la métrica o la del método de refactorización.

Figura 12. Diagrama del Caso de Uso Análisis Sinfáctico

Primero se encuentran las clases abstractas con sus funciones vimiales puras, posteriormente, se encuentran las clases derivadas a las abstractas y la implementación de las interfaces.

La Figura 13 muestra el diagrama del caso de uso Méfrica, que es invocado después del análisis sintáctico cuando se elige la opción de Calcular Métrica V-DINO.

Métrica

BaseDatDs

Cslc~ls V-DIN0

usuaria \ 1

Figura 13. Diagrama del Caso de Uso Métrica

45

Page 68: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

Primero se debe hacer el análisis sintáctico para posteriormente calcular la métrica basada en la información de la base de datos. De acuerdo al valor de la métrica se emite una interpretación del resultado, con la acción recomendada a seguir.

La Figura 14 muestra el diagrama del caso de uso Generar Arquitectura, que es invocado cuando se haga la refactorización. Este caso consiste en crear las nuevas clases intermedias para aplicar el método de refactorización, y transferir las interfaces a estas clases, juntando interfaces en una sola interfaz genérica.

Susoluir nierfaces s

Archiva Final Crear Template MeViod Crear Clase intermedia

Figura 14. Diagrama del Caso de Uso Generar Arquitectura

Primero se sustituyen las interfaces, creando una interfaz genérica. Por cada interfaz sustituida se crea una clase intermedia, con un método de plantilla para ligar a la interfaz genérica con la interfaz sustituida, que a su vez llegará a la implementación en las clases derivadas.

La Figura 15 muestra el diagrama del caso de uso Generar Cbdigo, que es invocado cuando se hace la refactorización. Aquí se implementan los métodos de plantilla, se cambian las clases derivadas para que reconozcan a la clase intermedia, se elimina lo que es innecesario del M A 0 0 y se ligan las llamadas con la nueva interfaz genérica.

Primero se mueven las interfaces sustituidas a las clases intermedias, implementando el método de plantilla, posteriormente se cambian las herencias de las clases derivadas hacia las clases intermedias. Se eliminan las funciones vacías que ya no sean necesarias y se cambian las llamadas a función.

46

Page 69: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

I""""-i Generar CMiw

Figura 15. Diagrama del Caso de Uso Generar Código

5.2. Diseño del Sistema Para diseñar el sistema se utilizaron varios patrones de diseño, con el fin de darle facilidades de extensión a la herramienta. Como se mencionó anteriormente, esta arquitectura permite la integración de otros dos métodos de refactorización al actual y se podrán agregar más en el futuro.

Se utiliza el patrón de diseño 'Singleton' para manejar las pantallas internas que tiene el sistema, de tal manera que sólo exista una instancia por pantalla y todas ellas están contenidas en la pantalla principal. Cada pantalla tiene acceso a la base de datos de manera directa.

La estructura de pantallas se muestra en la Figura 16, además se muestran otras clases que dan soporte a la aplicación.

En la Figura 16 se muestra la vista de la jerarquía de pantallas, con cada pantalla implementando el patrón 'Singleton'. Las clases BnseDatos, UtileriasArchivo, FiltroArchivos, UtiíeriasContador sirven para dar soporte a la aplicación en general, es decir, para todos los métodos de refactorización.

47

Page 70: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

Figura 16. Arquitectura del Sistema, Jerarquía de Pantallas

La pantalla base del sistema, Principal, es la que contiene todas las instancias de las pantallas específicas. Funciona como un contenedor para las pantallas internas, las cuales son accedidas a través de un conjunto de objetos de tipo menú.

La pantalla Principal cuenta con un objeto comando, de tipo Command, ya que existe una jerarquía especial de objetos del patrón 'Command', subclases de CommandPrincipal, que sirven para invocar a cada pantalla, utilizando el método ofrecido por el patrón 'Singleton' para crear y acceder al único objeto de tipo pantalla. También cuenta con múltiples objetos baseX de tipo BaseDatos, para verificar que todas las bases de datos específicas de los métodos de refactorización existan y estén disponibles para el sistema. Esta clase, aunque es parte de la interfaz, se considera el cliente del marco de pantallas y comandos creado, y es la Unica clase no reusable dentro de la arquitectura.

La jerarquía de pantallas internas inicia con la clase Framelnterno, que tiene agregados un objeto base, de tipo BaseDatos, y un objeto comando, de tipo Command, de tal manera que todas las pantallas internas tengan acceso a la jerarquía de comandos y a cualquier base de datos. Las pantallas específicas FrameX heredan de Framelnterno, y reciben como parámetros en su construcción a la base de datos específica que requiere la pantalla y los archivos originales seleccionados por el usuario que conforman al M A 0 0 en estudio. Cada pantalla FrameX tiene una jerarquía de comandos CommandX, para las acciones de objetos gráficos de la pantalla. Cada clase FrameX es la encargada de controlar su Única instancia, respetando el patrón 'Singleton', contando con un método instanciar0 para crear y acceder a dicho objeto.

La clase BaseDatos se encarga de manejar las conexiones a distintas bases de datos, y de hacer consultas SQL (Structured Query Language) para manejar los datos de las tablas; la clase UíileriusArcliivo es para manejar la apertura de archivos, así como la

48

Page 71: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

generación de archivos de respaldo; FiltroArchivos es una clase auxiliar a UtileriasArchivo para manejar los tipos de archivos a abrir; y finalmente la clase UíiieriasContador sirve para manejar la comparación de archivos en ia pantalla de Comparación, para observar las diferencias entre los archivos fuente originales y los archivos refactorizados, y funciones adicionales para análisis de código fuente.

Se utiliza el patrón de diseño ‘Command’ para manejar los eventos generados en las pantallas por los botones, menus y listas desplegables. Se maneja una clase de tipo ‘Command’ por acción, teniendo todos los comandos de una pantalla un ‘Command’ genérico que implementa el patrón ‘Template Method’. Aparte cada clase Command genérica cuenta con una instancia de la pantalla a la que corresponde, para acceder de manera directa a sus elementos y poderlos modificar. Y a través del objeto de pantalla se puede acceder a la base de datos.

La estructura de comandos se muestra en la Figura 17, con las agregaciones que tienen cada uno de los comandos genéricos de pantalla.

Figura 17. Arquitectura del Sistema, Jerarquía de Comandos

En la Figura 17 se muestra la vista de la jerarquía de comandos implementando el patrón ‘Command’. Cada clase representa una acción de un elemento de la interfaz gráfica. Para ejecutar dicha acción, se utiliza la interfaz ejecutar() declarada en la clase Command e implementada por todas las subclases.

Se muestran además una de las clases generadas por JavaCC para hacer el análisis sintáctico, CPPParser, invocado desde distintos comandos. Cada método de refactorización tiene su propio analizador, con su propio archivo CPPParser por ejemplo, incluido en un paquete con el nombre del método.

Se agregó además la funcionalidad de manejar usuarios del sistema, debido a que es necesario controlar los cambios que se le hagan a un MAOO, los cuales sólo deben ser hechos por el administrador del M A 0 0 y notificados a todos los usuarios del MAOO.

En la Figura 18 se muestra la vista de la jerarquía de clases que se encargan de hacer este control. Primeramente se tienen tres pantallas, FrameAccesos, FrameUsumios y FramePassword, para manejar los tipos de accesos al sistema, los

49

Page 72: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato
Page 73: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

5.3. Diseño Detallado del Sistema Para mostrar cómo funciona el sistema se muestran a continuación tres diagramas de secuencia, para indicar el flujo de mensajes principales entre las distintas clases de la aplicacibn.

En la Figura 19 se muestran las llamadas que ocurren cuando se seleccionan los archivos originales de un M A 0 0 para que estén disponibles dentro de la aplicación.

Figura 19. Diagrama de Secuencia para Seleccionar Archivos Originales

En este escenario intervienen las clases que dan soporte a la aplicación, como son las clases UtileriasArchivo, FiltroArchivos, y BaseDaios. La acción se inicia en la pantalla Principal, cuando el usuario elige el menú de Seleccionar Archivos Originales, lo cual crea un objeto de tipo CommandPrincipalOriginales. Esta clase está dentro de la jerarquía de comandos, y a través de su clase base se llama al método ejecutar(). La acción de este método consiste en abrir un cuadro de diálogo para seleccionar archivos con código en C++, crear opcionalmente la copia de seguridad del M A 0 0 e inicializar el sistema, borrando las bases de datos de todos los métodos e inicializando pantallas.

En la Figura 20 se muestra el flujo de mensajes cuando se elige calcular la métrica V-DINO.

Esta secuencia de mensajes es iniciada en la pantalla Principal, cuando se elige la opción de Calcular Métrica V-DINO. Se crea una instancia de la pantalla FrameMetricaDINO, a través del comando CommandPrincipalMefricaDINO, utilizando el método instanciar(), el cual es parte del patrón 'Singleton'. Esta pantalla cuenta con las acciones realizar el análisis de código y calcular la métrica para una clase abstracta.

51

Page 74: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

I I I

Figura 20. Diagrama de Secuencia para Calcular la Métrica V-DIN0

Primeramente se debe realizar el análisis del código del M A 0 0 seleccionado, utilizando el comando CommandMefricaDINOAnalizar. Este comando simplemente llama al análisis del método de Separación de Interfaces y se muestran las clases abstractas obtenidas del análisis. Posteriormente se calcula la métrica con el comando CommandMetricaDINOClase, obteniendo los valores que intervienen en la métrica y presentando una recomendación de acuerdo al valor calculado de V-DINO. Para evitar trabajo extra, se lleva un registro de cuando el análisis del código fuente ya ha sido realizado, para no hacerlo de nuevo, o para realizarlo en caso de ser necesario. El análisis de código fuente se realiza cuando se han seleccionado nuevos archivos originales, o cuando ha sido ejecutado un método de refactorización y fueron modificados los archivos.

En la Figura 21 se muestra el flujo de mensajes surgidos a partir de que el usuario elige la opción de Metodo de Separación de Interfaces.

De la misma forma que se creó la pantalla de la métrica se crea la pantalla FrameMetodoSepuracion. En caso de que no haya sido realizado antes, se realiza el análisis del código original del MAOO, utilizando para ello al analizador realizado en JavaCC representado por la clase CPPParser. El análisis arroja la información necesaria y suficiente para realizar la refactorización. El método es ejecutado por cada clase abstracta, verificando primero si es posible refactorizar, validando las precondiciones del método.

52

Page 75: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

IBII"-"----^------ I I I I I I I I I I I I I I I I I I I I

1 - 0 I I I I I n *-I I I I I 1 I I I I I I I I 1 I I I I I I I I I I I I

I 1 I I I I I I

b I I I

I I I I I

I I I t I I I I I I I I I I I I :E I I--, I I , I I - '[P

I I I I I I I

I I I I

I I I

I I I I I

Figura 21. Diagrama de Secuencia para Refactorizar

Si las precondiciones son satisfechas, se procede a refactorizar, sustituyendo las interfaces con firmas iguales, creando clases intermedias y sustituyendo llamadas a interfaces. AI finalizar este proceso, se hace la notificación a los demás métodos y métricas que los archivos originales ban cambiado, para que actualicen sus análisis.

Dentro de la herramienta son tres los procesos importantes: el análisis del código fuente de un MAOO, el cálculo de la métrica V-DIN0 y la aplicación del método de refactorización por Separación de Interfaces. A continuación se muestran los diagramas de actividades para cada uno de estos procesos.

En la Figura 22 se muestra el diagrama de actividades producto del método ejecurar() de la clase CommandMetodoSeparacionAnalizar.

Primeramente, para cada archivo del M A 0 0 original se realiza el proceso de análisis léxico y sintáctico, utilizando el analizador creado en JavaCC, el cual obtiene la información relevante del archivo, en cuanto a clases, métodos, objetos, herencias y llamadas a métodos. Se hace también otro análisis para encontrar directivas #Include.

53

Page 76: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

b-5 buscar directims Include

encontrar Clases Abstractas

\1

\1

J

\1

encontrar Funciones Viltuales

enconlrar Clases üerimdas

encontrar Implernentaci(m de Funciones Viltuales

encontrar Uamadas

Faltan No ‘A I mplernenladones

V (completar Métodm)

Figura 22. Diagrama de Actividades del Proceso de Análisis

La segunda parte del análisis se realiza cuando ya han sido analizados todos los archivos, y entonces se procede a llenar la base de datos encontrando las clases abstractas, las funciones virtuales y virtuales puras, las clases derivadas de las abstractas, las implementaciones de funciones virtuales en clases derivadas y las llamadas a funciones virtuales. Existe un proceso alterno que puede realizarse si no existen algunas implementaciones de funciones virtuales, y entonces se crean los registros de estas funciones de forma que se pueda completar la base de datos. Este proceso alterno ocurre cuando una clase derivada no implementa alguna función virtual pura, y por tanto esta clase derivada también se considera abstracta.

En la Figura 23 se muestra el diagrama de actividades producto del método ejecutar() de la clase CommandMetricaDINOCiase.

54

Page 77: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

O \1 / Obtener Clase Abstracta ')

4 f encontrar CNOC 1 - -

clase abstracta + A encontrar NFNO -

V-DIN0 = NFNO I (CNOC x NFV) + Implementatianes de funciones virtuales vadas

si V-OINO=O Recomendacibn: 25 No hay Pmblema

Pmblema NO Gme

Figura 23. Diagrama de Actividades del Cálculo de la Métrica

En este diagrama se muestra como se calculan los valores de la métrica, y posteriormente se realiza la recomendación de acuerdo al valor calculado. Si el valor es cero, se informa que no hay problema; si el valor es menor a 0.5000, se considera que el problema no es grave porque es muy probable que no se cumplan las precondiciones y cuando es mayor o igual a este valor sí se recomienda al usuario realizar la refactorización.

En la Figura 24 se muestra el diagrama de actividades producto del método ejecutar() de la clase ComtnandMeíodoSeparacionEjecutar.

Para llevar a cabo la refactorización para un árbol jerárquico en específico, es decir, para una clase abstracta con sus clases derivadas, primeramente se encuentran las funciones virtuales para realizar la validación de las precondiciones. Las precondiciones consisten en encontrar funciones con firmas iguales y que sean mutuamente excluyentes, como fue explicado anteriormente,

55

Page 78: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capitulo 5. Desarrollo del Sistema

NO

sustituif Llamadas O

Figura 24. Diagrama de Actividades de la Refactorización

Si s precondiciones son cumplidas, entonces se procede a rea--zar la refactorización, sustituyendo las funciones con firmas iguales por una interfaz genérica, la cual es colocada en la clase abstracta. Para cada interfaz sustituida se crea una clase intermedia. A las clases derivadas se les cambia la relación de herencia hacia las clases intermedias y se les eliminan las funciones no utilizadas.

5.4. Análisis del Código Fuente Para realizar el análisis léxico y sintáctico de los archivos de un MAOO, y para implementar las acciones semánticas asociadas al código reconocido se está empleando el generador de analizadores JavaCC [Java03], con una gramática para el lenguaje C++.

Java Compiler Compiler, JavaCC, es una herramienta generadora de analizadores léxicos y sintácticos (parsers) escrita en Java, que produce código en Java. Las características principales de este metalenguaje son:

Top-down.- Genera analizadores descendentes recursivos, esto permite el uso de gramáticas más generales. Especificaciones Iéxicas y gramáticas en un archivo.- Las especificaciones léxicas tales como expresiones regulares, cadenas, etc. y las especificaciones de la gramática (BNF) ambas son escritas juntas en el mismo archivo. Especificaciones sintácticas y semánticas hacia adelante "Lookahead".- Por defecto, JavaCC genera un analizador LL(I), esto es, sólo se analiza un token para realizar las acciones semánticas. Sin embargo, pueden haber porciones de la gramática que no sean LL(1). El analizador es LL(k) en determinados puntos, pero permanece LL(1) en cualquier otro lugar para un mejor desempeño. AI permitir un "Lookahead" mayor, se puede verificar toda una regla compuesta de varios tokens para llevar a cabo el reconocimiento de toda una instrucción o una acción semántica'.

56

Page 79: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

caoíhiio 5. Desarrollo del Sistema

Además JavaCC proporciona otras herramientas estándares relacionadas a la generación del parser, tales como la construcción de árboles (JJTree), Y la conversión de archivos de gramáticas JavaCC en documentos (JJDoc).

Se realizó un estudio del analizador sintáctico de la gramática del lenguaje C++ desarrollado en JavaCC por Sreenivasa Viswanadha [Visw96] llamado “CPlusPlus.jj”, el cual realiza el reconocimiento de código escrito únicamente bajo el estándar ANSI/ISO de C++. Esta herramienta tiene asociadas las siguientes clases que son de ayuda para el análisis del código fuente.

ClassScope Scope SymtabManager

Cuando se compila el archivo “CPlusPlus.jj” que contiene la gramática, JavaCC genera las siguientes clases:

CPPParser CPPParserConstants CPPParserTokenManager Simplecharstream ParseException Token TokenMgrError

Para detectar ciertos elementos de un programa escrito en C++ que son necesarios para el proceso de refactorización, se requirió hacer algunas modificaciones a la gramática original y agregar algunas reglas de producción. Este trabajo fue realizado por Leonor Adriana Cárdenas Robledo en [Card04]. Algunos de los elementos que no se reconocían y que fueron agregados son:

Declaración de objetos o punteros a objetos de referencia (objetos de tipo definido por el usuario). Declaración de objetos o punteros a objetos de referencia como parámetros. AI utilizar “new” Únicamente reconocía datos primitivos, ahora se permite usarlo con objetos de referencia. También se permite ahora que las funciones regresen objetos o punteros a objetos. Llamadas a métodos de objetos de tipos de datos de referencia.

También se detectaron los puntos dentro de la gramática en donde se deben introducir las acciones semánticas con el fin de obtener la información necesaria para llenar la base de datos que se emplea para aplicar el método de refactorización y el cálculo de la métrica.

Con JavaCC se generó el analizador, que fue integrado a la arquitectura existente del sistema como un paquete, por tanto el sistema completo cuenta con tres paquetes (uno por método de refactorización). El analizador generado con JavaCC sirve para llenar la base de datos del método, y los registros que se obtienen son los siguientes:

Reconocimiento de las funciones virtuales y funciones virtuales puras que estén declaradas y/o implementadas en los archivos originales.

57

Page 80: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

Reconocimiento de las clases que tienen declaradas en primera instancia a las funciones virtuales o virtuales puras. Estas clases serán denominadas Abstractas. Reconocimiento de la implementación de las funciones virtuales o vimiales puras que se encuentren en clases diferentes a las abstractas. Reconocimiento de las clases que en segunda instancia implementan a las funciones virtuales o virtuales puras. Estas clases serán denominadas Derivadas. Reconocimiento de las implementaciones vacías de funciones virtuales. Aquí se reconoce cuando una función sólo tiene las llaves de apertura y cierre, ó cuando SU código se considera nulo, ya que sólo tiene un retorno de valor nulo. Reconocimiento de las llamadas que existen hacia las funciones virtuales o virtuales puras.

Aparte se hace un análisis utilizando código en Java para encontrar la declaración de directivas #include.

Cabe mencionar que la gramática de C++ con la que se cuenta hasta el momento, y que fue desarrollada por [Visw96], está aún incompleta. Ya se cuenta con lo necesario para reconocer el problema de dependencia de interfaces, pero existen instrucciones que no son reconocidas por el analizador y generan errores en el análisis.

Las limitaciones del analizador creado son: El código de entrada debe de estar libre de errores gramaticales y sintácticos, es decir, debe ser compilable. No se reconocen clases parametrizadas, clases “templates”, en donde estos parámetros sean tipos de datos definidos por el usuario.

0 No se reconocen operaciones “cast” con objetos o tipos de datos. 0 No son reconocidas las macros.

Se ignoran las directivas del pre-procesador. o Existen limitaciones con la inicialización y uso de constructores de objetos.

Debe haber explícitamente la declaración de tipo de dato para las funciones. Los parámetros de las funciones deben tener un nombre y tipo explícito. No se reconocen los constructores y destructores, y el código de ellos.

El modelo entidad-relación de la base de datos, llamada BaseDatosSI, que es utilizada para recopilar la información, se muestra en la Figura 25. Esta base de datos fue implementada con el manejador de bases de datos MySQL.

La tablas que tiene la base de datos son: CA para clases abstractas, CD para clases derivadas, FVP para funciones virtuales puras, IMPLE para la implementación de una función virtual pura, LLAM para las llamadas a las funciones de interfaz, y PARAM para los parámetros de una función.

A continuación se mencionan cada una de las tablas de la base de datos, y se da una breve descripción de cada campo dentro de la tabla.

Tabla CA (Clase Abstracta) idCA. Identificador de la clase abstracta. nombreCA. Nombre de la clase abstracta. archivoH. Nombre del archivo .h en donde se encuentra declarada la clase abstracta. archivoC. Nombre del archivo .cpp en donde se encuentra implementada la clase.

58

Page 81: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

fnombrecA \

i

Tabla CD (Clase Derivada) idCD. Identificador de la clase derivada. nombrell). Nombre de la clase derivada. idCA. Identificador de la clase abstracta padre de la clase derivada. urchivoH. Nombre del archivo .h en donde se encuentra declarada la clase derivada. archivol. Nombre del archivo .cpp en donde se encuentra implementada la clase derivada. linenD. Línea en donde está la declaración de la herencia. l i n e d Línea en donde está la instrucción #include de la clase padre en el archivo .b.

Tabla FVP (Funciones Virtuales Puras) idFVP. Identificador de la función virtual pura. nombreFVP. Nombre de la función virtual pura. idCA. Identificador de la clase abstracta en donde está declarada la función virtual pura. reforno. Tipo de valor de retorno de la función viriual pura. linen. Línea en donde está declarada la función virtual pura dentro del archivo .h de la clase abstracta.

Tabla IMPLE (Implementación) idFVP. Identificador de la función virtual pura. idCD. Identificador de la clase derivada en donde está implementada la función virtual pura. vacia. Indica si está o no vacía la implementación. archivo. Nombre del archivo .cpp o .h en donde está la implementación.

59

Page 82: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

linea. Linea en donde está declarada la función dentro del archivo .h de la clase derivada. lineal. Línea en donde empieza la implementación de la función. linea2. Línea en donde termina la implementación de la función.

Tabla LLAM (Llamadas) idFVP. Identificador de la función virtual pura. linea. Linea en donde se encuentra la llamada a la función. archivo. Archivo .h o .cpp en donde se encuentra la llamada.

Tabla PARAM (Parámetro) idFVP. Identificador de la función virtual pura. tipoPARAM. Tipo de dato del parárnetro. nombrePARAM. Nombre del parámetro. apuntador. Indica si es o no un apuntador el parámetro.

5.5. Herramienta SR2 Refactoring La herramienta creada para resolver el problema de dependencia por interfaces no utilizadas se denomina “SR2 Refactoring” y forma parte del proyecto “ S E : Reingenieria de Software Legado para Reuso” [Sant02]. La pantalla principal de la aplicación se observa en la Figura 26.

El proyecto SR2 consta de otros métodos de refactorización aparte del descrito aquí, y por ello fue necesario crear una interfaz que englobara a estos otros métodos de refactorización, los cuales son: Método de Adaptación de interfaces [Sant04e] y Método de Reducción de Acoplamiento [Card04], ésta última implementa también la medición de la métrica COF (Coupling Factor) [Brit95]. Aparte el trabajo descrito aquí agrega el Método de Separación de interfaces y la Métrica V-DWO.

Como estos métodos de refactorización no serán los únicos en el proyecto, se diseñó la interfaz de tal manera que pueda soportar otras pantallas y métricas, y para ello se utilizaron los patrones de diseño ‘Singleton’ y ‘Command’ del catálogo de Gamma [Gamm95]. Esta arquitectura del sistema se explicó en la Sección “Diseño del Sistema”.

La pantalla cuenta con seis menús: Abrir para seleccionar archivos de origen, cambiar de sesión de usuario y para salir del sistema, Métricas para seleccionar la métrica V-DIN0 o la métrica COF (Coupling Factor), Métodos de Refactorización para seleccionar uno de los tres métodos disponibles, Comparación para comparar 10s archivos originales con los refactorizados, Usuarios para manejar los tipos de acceso y usuarios, y Ayuda para la información del sistema.

Para autenticar usuarios, ya sea cuando se entra por primera vez al sistema o cuando se cambia de sesión de usuario, se utiliza la pantalla mostrada en la Figura 27.

En esta pantalla se selecciona uno de los usuarios registrados en el sistema en la lista Usuario, escribiendo su nombre de usuario, Login, y su clave de acceso, Password. Se tienen tres oportunidades para escribir la clave correcta y entrar al sistema. De acuerdo al tipo de acceso que tenga especificado el usuario, se habilitan los menús que tiene derecho a usar. En esta pantalla también se puede modificar la clave de acceso, usando el botón de chequeo y escribiendo la nueva clave dos veces.

60

Page 83: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

Figura 26. Pantalla Principal de SR2 Refactoring

Para seleccionar los archivos originales, se cuenta con el cuadro de diálogo “Seleccionar Archivos Originales”, mostrado en la Figura 28, que permite abrir múltiples archivos fuente de C++ con las extensiones c, cpp, h y hpp. Después de seleccionar los archivos o agregar más a la selección actual, el sistema pregunta si se desea realizar copia de seguridad de estos archivos seleccionados, para conservar la versión original del M A 0 0 ya que los archivos seleccionados pueden ser modificados por alguno de los métodos de refactorización.

61

Page 84: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

a Fuerke üemento.h a R e s t w e . 1 @ Lista.q>p @ BubMe.cpp 1kta.h @ BubMe.h B Orde&xq.cpp @ Contextoxpp /ZJ ~eatemspp jiJ Context0.h @ 5 e c w . h

Figura 28. Diálogo para Abrir Múltiples Archivos

Se pueden elegir todos los archivos de un MAOO, y se muestran los archivos con extensiones válidas para C++. Con el botón Abrir se elegirán los archivos seleccionados para trabajar con ellos, borrando con esto todas las bases de datos y datos de pantallas, si se elige Cancelar no se modifica la selección y se conserva el estado del sistema.

En lo que compete al método de Separación de Interfaces, se cuenta con dos pantallas para hacer el análisis y solución del problema de dependencia de interfaces.

Figura 29. Pantalla de la Métrica V-DIN0

62

Page 85: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

La Figura 29 muestra la pantalla para el cálculo de la métrica V-DINO, que sirve como referencia al usuario para decidir si realiza o no la refactorización de su código fuente. Esta pantalla tiene el botón que realiza la ejecución del análisis sintáctico del código fuente, dicho proceso fue explicado en la Sección “Análisis del Código Fuente”.

La pantalla cuenta con el botón Realizar Andisis para ejecutar el análisis sintáctico del código y llenar la base de datos, después de este proceso se activa la lista desplegable Clases Abstractas que muestra a las clases con funciones virtuales puras. AI seleccionar una clase se muestran los valores de C-NOC, NFV, NFNO y V-DINO, aparte se muestra una Recomendacibn dependiendo del valor de la métrica.

La Figura 30 muestra la pantalla del método de separación, que sirve para modificar el M A 0 0 de origen del usuario según el método de refactorización. Esta pantalla también cuenta con el botón que realiza la ejecución del análisis sintáctico, permitiendo poder refactorizar sin pasar por la pantalla de la Figura 29, pero si el proceso ya fue hecho en dicha pantalla, no se vuelve a realizar.

Cuenta con el botón Analizar Código para ejecutar el análisis sintáctico del código y llenar la base de datos, después de este proceso se activa la lista desplegable Clases Abstractas que muestra a las clases con funciones virtuales puras o una opción de << Todas >> para hacer la refactorización sobre todas las clases abstractas. Se cuenta con el botón Ejecutar Método que será el encargado de realizar la refactorización automática, después de verificar que se cumplan las precondiciones del método y solicitar datos al usuario con respecto a las nuevas clases e interfaces.

63

Page 86: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

Esta interfaz fue enriquecida con una pantalla para comparar archivos, para verificar de manera visual los cambios hechos a los archivos originales, pero esto sólo está disponible si se eligió crear la copia de seguridad de los archivos fuente en la pantalla de la Figura 28. Dicha pantalla se muestra en la Figura 31.

Figura 31. Pantalla de Comparación de Archivos

La pantalla cuenta con dos secciones para mostrar un Archivo Fuente y un Archivo Refactorizado. En la primera muestra las copias de seguridad de los archivos, si es que se hicieron, y en la segunda se muestran los archivos seleccionados en el cuadro de diálogo de la Figura 28, ya sea modificados o sin modificar. Para seleccionar que archivos se desean visualizar, se utilizan las listas desplegables Fuentes y Refactorizados.

Se cuenta con un botón Comparar Líneas para obtener las líneas del archivo consideradas como Base (no sufrieron cambios en ambos archivos), las líneas consideradas como Nuevas (sólo están en el Archivo Refactorizado), las líneas Eliminadas (sólo están en el Archivo Fuente), y las líneas de Reuso (sólo si no se ha cambiado nada de los archivos).

Para realizar el registro de usuarios que tienen permiso de usar el sistema, se utiliza la pantalla mostrada en la Figura 32. Estos usuarios tienen derecho a usar sólo ciertas partes del sistema, especificadas en el tipo de Acceso de Usuario.

Se registra en esta pantalla el Nombre, Puesto, Fecha de Registro, Login y Acceso, el Password se toma como vacío cuando es un nuevo usuario, y se debe modificar en la pantalla de la Figura 28.

64

Page 87: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

-ni-

Figura 33. Pantalla de Tipos de Accesos

65

Page 88: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 5. Desarrollo del Sistema

Las acciones posibles en esta pantalla son: Modificar Usuario, para cambiar datos del usuario excepto la clave; Nuevo Usuario, para dar de alta un usuario; Guardar Usuario, para guardar cambios o un nuevo usuario; Cancelar Operación, para cancelar sin guardar cambios; y Eliminar Usuario, para borrar un usuario del sistema.

Para especificar los tipos de accesos, se utiliza la pantalla mostrada en la Figura 33, que permite crear accesos genéricos, que después se les asignarán B los usuarios. Aquí se especifica que menús son permitidos y que menús estarán desactivados. El menú Archivo y Ayuda están disponibles para todos los usuarios.

A cada tipo de acceso se le asigna un Nombre y una Descripción, y se seleccionan los menús disponibles para ese tipo de acceso. Los menús disponibles son Métricas, Métodos, Comparación y Usuarios. Las acciones que se pueden realizar en esta pantalla son: Modzycar Tipo, para cambiar datos del tipo de acceso; Nuevo Tipo, crear un nuevo acceso; Guardar Tipo, para guardar modificaciones o un nuevo registro; Cancelar Operación, para no guardar cambios; y Eliminar Tipo, para borrar un tipo de acceso, sólo si no está asociado a un usuario del sistema.

66

Page 89: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

Capitulo 6) EVALUACIdN EXPERIMENTAL

6.1. Caso de Prueba 1. MAOO de Listas Doblemente Ligadas Aquí se analiza un M A 0 0 hecho para manejar listas doblemente ligadas de tipos de datos básicos. Este M A 0 0 se presentó en [Sant04].

El programa cuenta con la funcionalidad adicional de hacer ordenación y búsqueda de datas, utilizando los algoritmos de ordenación por burbuja y búsqueda secuencial, respectivamente.

También se le colocó al M A 0 0 una clase CContexto para funcionar como la interfaz del MAOO. La arquitectura del M A 0 0 se muestra en la Figura 34 con toda la jerarquía de clases, excepto el archivo que funciona como cliente e invoca a la interfaz.

En el diagrama se observa que existe una clase abstracta CLista, la cual cuenta con dos interfaces Busqueda() y Ordena(), que a su vez son implementadas por las clases derivadas CBubble y CSecuenc.

Debido a la naturaleza del MAOO, existen funciones con implementación vacía.

67

Page 90: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

1 a I

Figura 34. Diagrama de Clases del Caso de Prueba 1 . M A 0 0 Original

La clase CBubbZe es la encargada del algoritmo de ordenación, por tanto implementa vacía a la interfaz Busqueda() ya que no la necesita. Lo mismo pasa con la clase CSecuenc, encargada del algoritmo de búsqueda, que implementa vacía a la interfaz Ordena() porque tampoco la necesita.

La validación de las precondiciones del método de Separación de Interfaces determina que las dos interfaces tienen la misma firma, debido a que reciben los mismos parámetros y tienen el mismo valor de retorno; y son mutuamente excluyentes, debido a que ninguna clase derivada implementa con código no nulo a ambas interfaces; por tanto es posible fusionar estas interfaces y aplicar la refactorización.

El cálculo de la métrica V-DIN0 arroja el siguiente resultado, analizando a la clase CLista: C-NOC = 2, NFV = 2, NFNO = 2, y V-DIN0 = 2 I ( 2 x 2) = 0.5000.

Este caso está justamente en el límite de la métrica V-DIN0 para considerarlo como grave. El caso presentado es uno de los casos más comunes del problema de dependencia de interfaces, el cual fue mostrado en la Tabla 2. Debido a que se cumplen las precondiciones y el análisis de V-DIN0 sugiere refactorizar, se procedió a utilizar el método de refactorización por Separación de Interfaces para mejorar la arquitectura del MAOO.

En el Anexo D se muestra el código del M A 0 0 original, para observar las implementaciones nulas, las llamadas hacia las interfaces y las relaciones de herencia.

Al aplicar el método de refactorización se obtiene la arquitectura mostrada en la Figura 35. En el Anexo D también se muestra el nuevo código generado por el método, la sustitución y eliminación de interfaces y las nuevas cl.ases.

Primeramente las dos interfaces problemáticas fueron sustituidas por la interfaz genérica AlgorilmoInterJaz( ), que cuenta con la misma firma que las interfaces anteriores. La interfaz Busqiieda() es trasladada hacia la recién creada clase intermedia

68

Page 91: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

CAlgorl, la cual será ahora la clase base de CSecuenc. La interfaz Ordena() es trasladada hacia la también nueva clase CAlgor2, la cual es la clase base de CBubble.

En ambas clases derivadas CBubble y CSecuenc se eliminan las implementaciones que no eran necesarias. Por último en la clase CContexto se sustituyen las llamadas que había hacia las interfaces originales por una llamada hacia la nueva interfaz genérica. En el M A 0 0 sólo existían dos llamadas.

Se procede a corroborar la mejora del M A 0 0 aplicando la métrica V-DIN0 al M A 0 0 resultante. Ahora existen tres clases abstractas, CLista, CAlgor1 y CAlgor2, por tanto se calcula V-DINO para cada una de ellas.

Para la clase CLista: C-NOC = 2, NFV = I , NFNO = O y V-DIN0 = 0.0000, Para CAlgorl y CAlgor2: C-NOC = 1, NFV = 1, NFNO = O y V-DIN0 = 0.0000.

Se puede observar, por los valores de la métrica, que el problema de dependencia por interfaces no utilizadas ha quedado totalmente resuelto en este MAOO.

Figura 35. Diagrama de Clases del Caso de Prueba 1. M A 0 0 Refactorizado

6.2. Caso de Prueba 2. MAOO de Estadistica Aquí se analiza un M A 0 0 del dominio de la estadística, el cual fue presentado en [ Sant04bl.

Este M A 0 0 proporciona algunas funciones para cálculo estadístico, utilizando tres listas doblemente ligadas para almacenar la serie de números sobre los que operan las funciones, también se cuenta con dos matrices para manejar operaciones adicionales.

La funcionalidad total que tiene el M A 0 0 completo es el cálculo de medidas de tendencia central, dispersiones, distribuciones, regresiones y correlaciones, y como auxiliares se tienen ordenaciones de datos y solución de sistemas de ecuaciones lineales.

El diagrama de clases completo se muestra en la Figura 36. Para simplicidad del gráfico, no se muestran todas las relaciones de agregación que existen entre las clases derivadas de CSlraiegy, que sirven para establecer comunicación entre clases hermanas.

69

Page 92: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

Figura 36. Diagrama de Clases del Caso de Prueba 2. M A 0 0 Original

En este M A 0 0 existen dos clases abstractas, CSfrafegy y aED. CSfrafegy cuenta con las interfaces GefResulfado(), Resuelve(), Ordena() y Calcula(), las cuales son implementadas por 29 clases derivadas, mostradas en la Figura 36. La clase aED cuenta con las interfaces GefED() y SefED(), implementadas con código en las clases cEDl, cED2, cED3 y cED4.

Por la intención de las interfaces, existen 71 funciones vacías en las clases derivadas de CStrategy. 28 corresponden a la interfaz Resuehe( ), 24 a la interfaz Ordena(), 13 a la interfaz GefResulfado() y cinco a la interfaz Calcula(). No existen funciones vacías para la clase aED.

La validación de las precondiciones del método de Separación de Interfaces determina que las interfaces Ordena(), Resuelve() y Calcula() tienen la misma firma, y son mutuamente excluyentes, por tanto es posible fusionar estas interfaces y aplicar la refactorización. Como la interfaz GetResulfado() no cumple con las precondiciones, no será posible resolver el problema para esta interfaz.

El calculo de la métrica V-DIN0 arroja el siguiente resultado para la clase CSfrafegy: C-NOC = 29, NFV = 4, NFNO = 71, y V-DIN0 = 71 / (29 x 4) = 0.6120. Para la clase aED: C-NOC = 4, NFV = 2, NFNO = O, y V-DIN0 = 0.0000.

70

Page 93: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

El caso de CStrategy está dentro de los límites de la métrica V-DIN0 para considerarlo como grave. Debido a que se cumplen las precondiciones y el análisis de V-DIN0 sugiere refactorizar, se procedió a utilizar el método de refactorización por Separación de Interfaces para mejorar la arquitectura del MAOO.

En el Anexo E se muestra parte del código del M A 0 0 original, para observar las implementaciones nulas, las llamadas hacia las interfaces y las relaciones de herencia. Se tomó como muestra a tres clases de las 29 derivadas que implementan a una interfaz diferente.

AI aplicar el método de refactorización se obtiene la arquitectura mostrada en la Figura 37. En el Anexo E también se muestra el nuevo código generado por el método, la sustitución y eliminación de interfaces y las nuevas clases.

Figura 37. Diagrama de Clases del Caso de Prueba 2. M A 0 0 Refactorizado

Primeramente las tres interfaces problemáticas fueron sustituidas por la interfaz genérica AlgoritmoZnterfaz( ), que cuenta con la misma firma que las interfaces anteriores. La interfaz Ordena() es trasladada hacia la recién creada clase intermedia CAlgorl, la cual será ahora la clase base de CBubble, CShell, CInserc y CSelec. La interfaz Resuelve() es trasladada hacia la también nueva clase CAlgor2, la cual es la clase base de CGaussJor. La interfaz Calcula() es trasladada hacia la clase CAlgor3, la cual es la clase base de 25 clases que implementan calculos estadísticos.

En todas las clases derivadas se eliminan las implementaciones que no eran necesarias, 58 en total, exceptuando a las de la interfaz GetResu/fado( ), que no participa en la refactorización. Por último en la clase CContexio y en otras clases se sustituyen las llamadas que había hacia las interfaces originales por una llamada hacia la nueva interfaz genérica. En el M A 0 0 existían 14 clases que realizaban llamadas hacia las interfaces anteriores.

Se procede a corroborar la mejora del M A 0 0 aplicando la métrica V-DIN0 al M A 0 0 resultante. Ahora existen cinco clases abstractas, CSfrafegy, aED, CAlgorl,

71

Page 94: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

CAlgor2 y CAlgor3, por tanto se calcula V-DIN0 para cada una de ellas. No se muestra el cálculo para aED porque es el mismo que antes,

Para la clase CStrategy: C-NOC = 3, NFV = 2, NFNO = O y V-DIN0 = 0.0000, Para CAlgorl: C-NOC = 4, NFV = 2, NFNO = 4, y V-DIN0 = 0.5000. Para CAlgor2: C-NOC = 1, NFV = 2, NFNO = 1 y V-DIN0 = 0.5000. Para CAlgor3: C-NOC = 24,

Se puede observar, por los valores de la métrica, que el problema de dependencia por interfaces no utilizadas ha quedado parcialmente resuelto en este MAOO, pero ha sido disminuido considerablemente en las clases del árbol de CAlgor3. La clase abstracta CStrategy ya no tiene el problema.

En este M A 0 0 es imposible realizar nuevamente la refactorización para CAlgorl y CAlgor2, ya que sus dos interfaces no cumplen las precondiciones del método. Esto es porque las interfaces Ordena() y Resuelve() tienen diferenes firmas con respecto a la interfaz GetResultado().

6.3. Caso de Prueba 3. M A 0 0 de Graficación Aquí se analiza un M A 0 0 para realizar gráficas en dos dimensiones, el cual está siendo usado en conjunto con el M A 0 0 de estadística presentado en la sección 6.2.

Este M A 0 0 proporciona funciones para graficación de botones, puntos, y los ejes para una gráfica de puntos, utilizando una lista doblemente ligada para almacenar la serie de números sobre los que operan las funciones. También cuenta con la funcionalidad de la operación del ratón.

El diagrama de clases completo se muestra en la Figura 38 con toda la jerarquía de clases, excepto el archivo que funciona como cliente e invoca a la interfaz, la cual está implementada en la clase -ContxEjesH.

Debido a las limitaciones del analizador sintáctico, las cuales ya fueron mencionadas en la sección 5.4, no fue posible incluir dentro del estudio a las clases - Lista, -ListaG y -Elemento, ya que estas clases están implementadas a base de métodos plantilla o templates, los cuales no son reconocidos por el analizador. Asimismo, se realizaron algunos cambios dentro del código fuente para que fuera reconocida la mayor parte del código de acuerdo a las limitaciones, siendo el cambio más importante la eliminación de la interfaz GetBoton() de la clase -Figura y todas SUS

clases derivadas debido a que esta interfaz utilizaba como valor de retorno un objeto de la clase Elemento.

En este M A 0 0 existen dos clases abstractas, -Context1 y -Figura. Existe otra clase que se considera como abstracta, la clase Circulo, debido a que esta clase hereda de -Figura pero no implernenta todas las interfaces. -Context1 cuenta con la interfaz - Inferactua(), la cual es implementada con código por su clase derivada -ContxEjesXY, mostrada en la Figura 36.

La clase -Figura cuenta con las interfaces Show(), Hide() , Push() , GetTx(), GeiColor(), SetColorF() y Cursor-fN(), implementadas en las clases Boton, Circulo, - EjeX, -.EjeY, -SJJSXY, GPunto, Linea y Paleta. Como se explicó, la clase Circulo cuenta con funciones virtuales puras ya que no implementa a cinco de las interfaces de - Figura, pero no cuenta con clases derivadas.

NFV = 2, NFNO = 8 y V-DIN0 = 0.1667.

72

Page 95: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

U

Figura 38. Diagrama de Clases del Caso de Prueba 3. M A 0 0 Original

Por la intención de las interfaces, existen 29 funciones vacías en las clases derivadas de -Figura. La clase Boron no tiene implementaciones vacías; la clase Paleta implementa vacías a las interfaces Show(), Hide(), Push() y SelColorF(); las clases Linea, GPunto, -EjeX, -EjeY y -SysXY implementan vacías a las interfaces Push( ), GetTx(), GetColor(), SetColorF() y Cursor-IN(); la clase Circulo sólo implementa con código a las interfaces Show( ) y Hide( ) y a las demás interfaces no las implernenta, por lo que siguen quedando como funciones virtuales puras en esta clase derivada y no cuentan como implementaciones vacías. No existen funciones vacías para la clase -Context/ ni para la clase Circulo.

La validación de las precondiciones del método de Separación de Interfaces sobre la clase Figura determina que la interfaz GeiTx() no tiene una firma igual con algún otra función, por tanto no puede unirse con ninguna función y sustituirse, lo mismo pasa con las interfaces Getcolor( ), SetColorF( ) y Cursor-IN( ), y hubiera pasado con la interfaz GetBoton( ) que fue eliminada en el preanálisis por las limitaciones del analizador. Por tanto, no se puede emplear el método para resolver el problema con estas interfaces.

La validación de las precondiciones también descubre que las interfaces Show(), /fide() y Push() tienen la misma firma, pero no son mutuamente excluyentes, por tanto

73

Page 96: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

110 es posible fusionar estas interfaces y aplicar la refactorización. No son mutuamente excluyentes debido a que la clase Boton implementa con código a las tres interfaces, y con esto se deduce que todas las interfaces son utilizadas y no se pueden eliminar.

El cálculo de la métrica V-DIN0 arroja el siguiente resultado para la clase P-igui-a: C-NOC = 8, NFV = 7, NFNO = 29, y V-DIN0 = 29 / (8 x 7) = 0.5178. Para la

Clase Contextí: C-NOC = I , NFV = 1, NFNO = O, y V-DINO = O.OOOO. Para la clase Cii-cu¡o: C-NOC = O, NFV = 5 , NFNO = O, y la métrica V-DIN0 no se puede calcular, debido a que no hay clases derivadas.

El caso de -Figura está dentro de los límites de la métrica V-DIN0 para considerarlo como grave. Debido a que no se cumplen las precondiciones, aunque el análisis de V-DIN0 sugiere refactorizar, no se puede utilizar el método de refactorización por Separación de Interfaces para mejorar la arquitectura del M A 0 0 y' habría que buscar otras alternativas para resolver el problema.

En el Anexo F se muestra parte del código del M A 0 0 original, para observar las implementaciones nulas y las relaciones de herencia.

6.4. Caso de Prueba 4. Herramienta de Modelado de Objetos En este caso se analiza una herramienta llamada Graf03D del dominio de la visión artificial, la cual fue presentada en [Diaz04].

La herramienta Graf03D permite generar y crear modelos gráficos en un entorno tridimensional a partir de primitivas predefinidas, así mismo, estos modelos pueden ser manipulados y editados para cambiar sus características propias como lo son: color, tamaño, posición, etc. Esta herramienta es utilizada como auxiliar para reconocimiento de patrones y modelado de procesos de manufactura, por mencionar algunos usos.

La herramienta completa cuenta con una interfaz gráfica, un generador de archivos de texto para definir en forma textual la descripción de los objetos, un analizador léxico y sintáctico para validar la información y un generador de modelos gráficos, ya sea a partir de los archivos de texto o realizando el proceso contrario.

De la arquitectura completa de la herramienta sólo se tomó la jerarquía de clases especializada en el manejo de los objetos visuales que son parte de la interfaz gráfica de la herramienta. No se tomarán en cuenta las demás partes de la herramienta para simplificar el estudio. Se realizaron modificaciones a esta arquitectura para poder utilizar el método debido más que nada a las limitaciones del analizador sintáctico utilizado para este proyecto de investigación.

El diagrama de clases de este M A 0 0 de objetos visuales se muestra en la Figura 39. Esta arquitectura cuenta con una herencia múltiple, teniendo como clases base a las clases Material y Transform, siendo la primera la encargada de dar la funcionalidad de las propiedades de los objetos visuales y la segunda la encargada de los movimientos del objeto.

En este M A 0 0 existe una clase abstracta, Material. Material cuenta con las interfaces Setpoints(), Getpoinis(), Setradius(), Setlineas() y Getlineas(), las cuales son implementadas por las siete clases derivadas A Torus, ABaseCyl, Points, APoIyhedron, Triangle, Line y CPolygon, mostradas en la Figura 39.

Por la intcnción de las interfaces, existen 24 funciones vacías en las clases derivadas de Mater id . Cinco corresponden a la interfaz Setpoinls(), cinco a la interfaz Getpoinls(), cuatro a la interfaz Setradius(), cinco a la interfaz Setlineas() y cinco a la interfaz Geiliiiea.v().

74

Page 97: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capitulo 6. Evaluación Experimental

I

I I

f

Figura 39. Diagrama de Clases del Caso de Prueba 4. M A 0 0 Original

La validación de las precondiciones del método de Separación de Interfaces determina que las interfaces Setpoints( ), Setradius() y Setlineas( ) tienen la misma firma, y son mutuamente excluyentes, por tanto es posible fusionar estas interfaces y aplicar la refactorización. Como las interfaces Getpoints() y Getlineas() no cumplen con las precondiciones debido a que tienen firmas diferentes, no será posible resolver el problema para estas interfaces.

El cálculo de la métrica V-DiNO arroja el siguiente resultado para la clase Material: C-NOC = 7 , NFV = 5 , NFNO = 24, y V-DIN0 = 24 / (7 x 5) = 0.6857.

El caso de Material sobrepasa los límites de la métrica V-DINO y entonces el problema se considera grave. Debido a que se cumplen las precondiciones y el análisis de V-DIN0 sugiere refactorizar, se procedió a utilizar el método de refactorización por Separación de Interfaces para mejorar la arquitectura del MAOO..

En el Anexo G se muestra parte del código del M A 0 0 original, para observar las implementaciones nulas y las relaciones de herencia. Debido a que no se tomó el resto de las clases de la herramienta Graf03D, no existen llamadas hacia las interfaces.

AI aplicar el método de refactorización se obtiene la arquitectura mostrada en la Figura 40. En el Anexo G también se muestra el nuevo código generado por el método, la sustitución y eliminación de interfaces y las nuevas clases.

75

Page 98: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

9L

Page 99: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 6. Evaluación Experimental

Para la clase Material: C-NOC = 3, NFV = 3, NFNO = O y V-DIN0 = 0.0000. Para CAlgorl: C-NOC = 3, NFV = 3, NFNO = 6, y V-DINO = 0.6667. Para CAlgor2: C-NOC = 2, NFV = 3, NFNO = 2 y V-DIN0 = 0.3333. Para CAlgor3: C-NOC = 2 , NFV = 3, NFNO = 2 y V-DIN0 = 0.3333.

Se puede observar, por los valores de la métrica, que el problema de dependencia por interfaces no utilizadas ha quedado parcialmente resuelto en este MAOO, pero ha sido disminuido considerablemente en las clases de los arboles de CAlgor2 y CAlgorS. La clase abstracta Material ya no tiene el problema.

En este M A 0 0 es imposible realizar nuevamente la refactorización para CAlgorl, ya que sus tres interfaces no cumplen las precondiciones del método. Esto es porque las interfaces GetpointsO y Getlineas() tienen diferentes firmas con respecto a la interfaz Setradius().

Resumen de Resultados En la Tabla 3 se muestran los resultados obtenidos en las pruebas. El análisis se hace por cada clase abstracta del MAOO. Se muestra el total de clases derivadas (C-NOC), el número de funciones virtuales (NFV), el total de funciones implementadas con código nulo (NFNO), y el valor de la métrica (V-DINO).

Se puede observar que en los tres de los cuatro MAOO’s utilizados como casos de estudio se mejora el diseño, ya que se reduce el número de implementaciones vacías o nulas y, por ende, la métrica V-DINO.

77

Page 100: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 7. Conclusiones y Trabajo Futuro

Capítulo 7) CONCLUSIONES Y TRABAJO FUTURO - I

Conclusiones El objetivo de todo el proyecto SR2 es el mejor aprovechamiento del software legado existente, para producir nuevas aplicaciones de mejor calidad. Para lograr esto se lleva software procedural hacia el paradigma orientado a objetos, y con ello se busca obtener las cualidades de reuso y extensión que tiene el software que respeta los principios de la tecnología orientada a objetos.

El proyecto SR2 se encuentra actualmente en la última fase de desarrollo, que consiste en implementar métodos de refactorización que ayudan a mejorar la arquitectura de MAOO’s, no con la finalidad de mejorar el funcionamiento actual de los MAOO’s, sino para permitir el reuso de los componentes en otras aplicaciones o extender la funcionalidad del MAOO, los cuales son aspectos a considerar para mejorar la calidad de un producto de software.

AI utilizar la herramienta desarrollada en esta tesis, en conjunto con el resto del proyecto SR2, se puede hacer reuso de software legado, obteniendo código con mayor calidad, ya que está basado en múltiples principios y patrones de diseño.

Las aportaciones de esta tesis son:

Page 101: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capitulo 7. Conclusiones y Trabajo Futuro

1.- Método de refactorización denominado Separación de Interfaces. El método tiene la intención de reducir el número de dependencias entre clases debido a la implementación de interfaces no utilizadas. Con esto se busca incrementar las cualidades de reuso y extensión de los MAOO’s. Mediante la refactorización propuesta, los programas que eran rígidos y frágiles por depender de interfaces que no ocupan ahora serán flexibles y robustos, y su mantenimiento será más fácil. Son flexibles porque se permite la extensión de la funcionalidad sin necesidad de modificar al MAOO, como se mostró en los ejemplos; son robustos porque ya no se producen errores en otras partes del M A 0 0 al modificar una interfaz o una clase, debido a que se reducen las dependencias por la separación de las interfaces. Una vez que el M A 0 0 se encuentra refactorizado, es más fácil de entender la estructura e intención de cada clase, ya que las clases sólo implementarán las interfaces que necesitan, y quedarán agrupadas por su intención en una misma clase intermedia. Se creó una precondición para el método, que exige que las interfaces que pueden sustituirse deben tener los mismos parámetros de entrada y salida, y estas interfaces deben ser mutuamente excluyentes. Esto es debido a que se hace el agrupamiento de clases y una clase no puede pertenecer a dos grupos. Aparte de esta precondición, al algoritmo se le agregó la precondición básica de no repetir nombres existentes en las nuevas clases que serán añadidas al sistema, con el fin de que el sistema no falle después de la refactorización. También se encontró un uso adicional para el método de Separación de interfaces, el cual es preparar a un M A 0 0 para ser llevado hacia Servicios Web. Esto es debido a que un Servicio Web debe ofrecer interfaces bien definidas para ser usadas por los usuarios del servicio, los cuales no conocen la implementación o estructura del servicio, que es visto por ellos como una caja negra. Por tanto, si un M A 0 0 tiene el problema de dependencia de interfaces, no podrá ser llevado a Servicio Web de forma eficiente debido a que el servicio ofrecerá interfaces que llevan a código nulo. Esto fue publicado en [Sant04].

2.- Métrica orientada a objetos denominada V-DINO. Debido a que no existe documentación en cuanto a cómo medir y evaluar la dependencia de interfaces debido a implementaciones vacías o nulas, se diseñó e implementó la métrica V-DMO (Valdés - Dependencia por Interfaces que No se Ocupan) para poder tomar una decisión acertada en cuanto a realizar la refactorización o saber hasta que grado un M A 0 0 tiene el problema. Esta métrica puede ser utilizada como una medida de la calidad de un software. En el estándar IS0 9126 [ISO91], el cual fue establecido para caracterizar la calidad del software, hay seis atributos que el software debe cumplir para ser considerado como un software con calidad: funcionalidad, confiabilidad, usabilidad, eficiencia, mantenibilidad y portabilidad. La métrica V-DIN0 puede medir objetivamente el grado de soporte a cambios o extensibilidad, el cual es un factor clave en la mantenibilidad de cualquier software.

79

Page 102: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 7. Conclusiones y Trabajo Futuro

3.- Casos de estudio que demuestran la efectividad del método v la métrica. Mediante las pruebas experimentales se ha demostrado que es correcta la propuesta de que los patrones de diseño ‘Strategy’ y ‘Template Method’ sirven para separar las interfaces. AI aplicar este método de refactorización a un MAOO, se logra reducir la dependencia entre clases abstractas y sus clases derivadas. Con esto se reduce la dependencia por interfaces que las clases derivadas no ocupan, de tal manera que las clases derivadas pueden ser reusadas de forma separada. Como resultado de la refactorización, se obtendrán MAOO’s que no requerirán de modificaciones cuando se quiera agregar nueva funcionalidad, respetando así el principio de Abierto / Cerrado [Meye98], y las nuevas clases sólo declararán interfaces que requieren, respetando así el principio de Separación de Interfaces del diseño orientado a objetos [Mart96]. Sin importar que tan alto o bajo sea el valor de la métrica, ha quedado demostrado que un M A 0 0 sí es mejorado si cumple con las precondiciones establecidas en el algoritmo de Separación de Interfaces.

4.- Herramienta de refactorización denominada SRZ Refactoring. Se implementó el método de refactorización de Separación de Interfaces en lenguaje Java para refactorizar código en C++, implementando el analizador léxico y sintáctico en el metalenguaje JavaCC. Lo mismo se hizo para implementar la métrica V-DINO. Para preparar la herramienta para tener vanos métodos y métricas se hizo su diseño basado en 10s patrones de diseño ‘Singleton’ y ‘Command’. Con ello se logró integrar los métodos de refactorización de Reducción de Acoplamiento [Card041 y Adaptación de Interfaces [Sant04e], así como la métnca COF [Brit95]. En un futuro se pueden añadir otros métodos y métricas de forma fácil.

Publicaciones Este tema de tesis ha sido difundido por medio de múltiples publicaciones en foros nacionales e internacionales. En cada publicación se ha buscado mostrar el método de refactorización por Separación de Interfaces, la métrica V-DIN0 o la herramienta SR2 Refactoring, siempre mostrando el trabajo realizado desde distintas perspectivas, como desde el punto de vista de la refactorización, el reuso, los patrones de diseño o incluso Servicios Web.

Las publicaciones son las siguientes: 1. “Método de Refactorización de Frameworks: Separación de Interfaces”

[Sant03a] 2. “Refactorización de Frameworks por la Separación de Interfaces” [Sant03c] 3. “Preparing Frameworks to become Web Services”’[SantO4] 4. “An Object-Oriented Metric to Measure the Degree of Dependency due to

Unused Interfaces” [Sant04a] 5. “Achieving Software Reuse Using the Interface Separation Principle of Object-

Oriented Design” [Sant04h]

80

Page 103: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Capítulo 7. conclusiones y Trabajo Futuro

“Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces” [Sant04c] “Using Design Patterns to Solve the Interface Dependency Problem” [Sant04d]

También se ha colaborado en otras publicaciones que no tratan directamente el

“Adaptación de Interfaces de Marcos de Aplicaciones Orientados a Objetos, Utilizando el Patrón de Diseño Adapter” [Sant03b] “Frameworks as Web Services” [Frag04] “Dynamic Configuration between Proxy Caches within an Intranet” [Sosa041 “Servicios Web para el Desarrollo de Software” [Frag04a]

6.

7.

tema de esta tesis. Estas publicaciones son: I .

2. 3. 4.

Trabajo Futuro Lo que resta de realizar en el proyecto SR2 es simplemente agregar más métodos de refactorización al sistema SR2 Refactoring. Existen demasiados métodos propuestos en la literatura consultada ([Keri03], [OCin99] y [Toku99]) pero la mayoría no han sido implementados en herramientas automáticas, por tanto existe todavía una amplia gama de posibilidades en este aspecto.

Inclusive existen otros patrones de diseño de Gamma [Gamm95] que pueden ser implementados para resolver problemas de diseño, no necesariamente utilizando la intención original de los patrones, como fue el caso de los patrones ‘Strategy’ y ‘Template Method’, usados en esta tesis. Asimismo existen otros catálogos de patrones que podrían ser empleados.

En lo concerniente a la herramienta realizada en esta tesis, aún se puede disminuir más la dependencia por interfaces no necesitadas, buscando un método alternativo al de Separación de Interfaces, cuando no se cumplen las precondiciones de este método. Una opción para esto sena implementar el algoritmo sugerido en [Keri03].

Otro trabajo que queda a futuro es completar la gramática de C++ de JavaCC para que reconozca la totalidad del lenguaje C++ estándar. Esto ayudará a crear mejores analizadores sintácticos, no sólo para este método, sino para futuros métodos, ya que se tendrán bases de datos más completas y se podrá ampliar la gama de programas que son reconocidos y refactorizados.

El proyecto SR2 también tomará el rumbo de la tecnología de Servicios Web, para ofrecer de una manera más fácil a los desarrolladores de software las herramientas de reestructura y refactorización. De ahí que otro trabajo futuro es la transformación de las herramientas de reestructura y refactorización, como la presentada en esta tesis, hacia Servicios Web, utilizando una metodología como la presentada en [Vasq04]. Estos servicios pueden entonces ser publicados en la red, utilizando tecnología como la presentada en [DelfD4]. De esta manera se tiene visualizado que los administradores de MAOO’s tendrán a su disposición el proyecto SR2.

81

Page 104: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo A. V-DIN0 como Métrica de Cohesión

Anexo A) V-DIN0 COMO MÉTRICA DE COHESIÓN

Cohesión

El concepto de cohesión ha sido usado con referencia a módulos o sistemas modulares. Mide el grado de unión con el cual características relacionadas de un programa están agrupadas en sistemas o módulos. Se asume que mientras más encapsuladas estén ciertas características relacionadas, el sistema será más confiable y con más fácil mantenimiento [Fent97].

De manera general, las características que debe cumplir la cohesión son las siguientes: Se espera que la cohesión no sea negativa y, más importante, que esté normalizada para que la medición sea independiente del tamaño del sistema modular o módulo. Además, si no hay relaciones internas en un módulo o en todos los módulos del sistema, se espera que la cohesión sea nula para ese módulo o sistema, ya que, si no hay relaciones entre los elementos entonces no existirá evidencia para decir que deben ser encapsulados juntos. Relaciones internas adicionales en un módulo no pueden disminuir el valor de la cohesión, ya que estas relaciones darían mayor evidencia de la dependencia entre los elementos y que deben estar encapsulados juntos. Cuando se

82

Page 105: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo A. V-DIN0 como Métrica de Cohesión

fusionan dos o más módulos que no tienen relaciones entre sí, la cohesión no puede incrementarse porque elementos no relacionados están agrupados juntos [Bria96].

A continuación se muestra la definición formal de la cohesión en un módulo con sus cuatro propiedades, basada en la teoría de conjuntos. Posteriormente se muestra cómo se cumplen estas propiedades para la métrica V-DINO.

Definición de Cohesión de un Módulo [Bria96] La cohesión de un módulo m = <E,,R,> de un sistema modular MS, donde E, es el conjunto de los elementos del módulo y R, es el conjunto de las relaciones entre los elementos, es una función Cohesión(m) caracterizada por las siguientes cuatro propiedades de cohesión.

Propiedad 1 de Cohesión: No negatividad y Normalización La cohesión de un módulo m = <E,,R,> de un sistema modular MS = <E,R,M> se encuentra dentro de un intervalo especificado

Cohesión(m) E [O,Max]. La normalización permite comparaciones significativas entre las cohesiones de

diferentes módulos, ya que todas pertenecen al mismo intervalo.

Propiedad 2 de Cohesión: Valor Nulo La cohesión de un módulo m = <E,,R,> de un sistema modular MS = <E,R,M> es nula si R,,, está vacío, es decir

R, = 0 => Cohesión(m) = O. Si no hay relaciones entre los elementos de un módulo, entonces la cohesión del

módulo es nula.

Propiedad 3 de Cohesión: Monotonicidad Sean MS’ = <E,R’,M’> y MS” = <E,R”,M”> dos sistemas modulares (con el mismo conjunto de elementos E) de tal manera que existan dos módulos m’= <E,,R,’> y m” = <E,,R,”> (con el mismo conjunto de elementos E,) pertenecientes a M’ y M” respectivamente, de tal forma que R’ - R,’ = R” - R,”, y R,’ E Rm”. Entonces,

Cohesión(m’) _< Cohesión(m”). Al añadir más relaciones entre los elementos de un módulo no se disminuye la

cohesión modular.

Propiedad 4 de Cohesión: Módulos Cohesivos Sean MS = <E,R,M> y MS’ = <E,R,M’> dos sistemas modulares (con el mismo sistema <E,R>) de tal forma que M’ = M - {m,,m2} u {m’}, con mi E M, m2 E M, m’ E M, y m’ = mi u mz (Los dos módulos mi y mz son reemplazados por el módulo m’, unión de ml y m2). Si no existen relaciones entre los elementos que pertenecen a ml y mz, entonces

max { Cohesión(mi), Cohesión(m2) } 2 Cohesión(m’). La cohesión de un módulo obtenido por unir dos módulos no relacionados no es

mayor que la máxima cohesión de los dos módulos originales.

83

Page 106: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo A. V-DIN0 como Métrica de Cohesión

Demostración

Recordando, la fórmula de la métrica V-DIN0 es: NFNO V - DIN0 =

C - N O C X N F V donde NFNO es el número de interfaces con implementación vacía en las clases derivadas, C-NOC es el número de clases derivadas y NFV es el número de interfaces o funciones virtuales puras.

Para hacer la demostración de estas propiedades para la métrica V-DIN0 se harán las siguientes consideraciones:

Se considera como sistema modular MS a cualquier M A 0 0 que tenga clases abstractas. Se considerarán como módulos m a diferentes árboles jerárquicos de clases que inicien con una clase abstracta, es decir, que tenga mínimo una función virtual pura, y que tenga al menos una clase derivada. Se considera como conjunto de elementos E ai conjunto de funciones virtuales, tanto en las clases abstractas como en las derivadas. Esto quiere decir que en E se encuentran las funciones virtuales NFV de la métrica V-DIN0 y cada implementación, ya sea con código o sin él, de estas funciones en las clases derivadas C-NOC de la métrica V-DINO, por tanto [El = C-NOC x NFV. Se considera como conjunto de relaciones R entre un elemento E’ y un elemento E” al conjunto de relaciones de tipo: E’ es implementada vacía en E”. Esto quiere decir que se considera como R a cada implementación sin código considerada en el NFNO de la métrica V-DINO, por tanto IR1 = NFNO. Por último, se considera como función Cohesión(m) a la métrica V-DINO(m).

Propiedad 1 d e Cohesión: No Negatividad y Normalización Primeramente se demostrará la propiedad de no negatividad. Como se especificó previamente, la métrica aplica para un árbol jerárquico de clases que inician por una clase abstracta (tiene ai menos una función virtual pura), que cuenta con al menos una clase derivada, por tanto C-NOC > O y NFV > O. NFNO es el total de implementaciones vacías, por tanto, NFNO 1 O.

Como todos los miembros de la fórmula de V-DIN0 son positivos, es obvio que V-DIN0 1 O, por tanto se demuestra la primera parte de la propiedad 1.

Para demostrar la normalización, se tiene que el máximo número posible de implementaciones vacías es C-NOC x NFV, por tanto, NFNO 5 (C-NOC x NFV). De ahí se tiene que

V-DINO(m) E [0,1], es decir, la métrica V-DIN0 está en el intervalo de O a 1 para todos los casos.

Propiedad 2 de Cohesión: Valor nulo Esta propiedad pide que cuando el conjunto R de relaciones está vacío, el valor de cohesión debe ser nulo. Para la métrica V-DIN0 se considera que R = 0 cuando no hay relaciones en donde una interfaz es implementada vacía en una clase derivada, es decir, NFNO = O.

84

Page 107: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo A. V-DIN0 como Métrica de Cohesión

Entonces se tiene que V-DIN0 = O / (C-NOC x NFV) = O, lo cual demuestra que R = 0 => V-DINO(m) = O.

Propiedad 3 de Cohesión: Monotonicidad Esta propiedad especifica que la cohesión no debe disminuir si se aumenta el número de relaciones a un módulo. Para la métrica V-DIN0 se dirá entonces que el valor de la métrica no debe disminuir si en un árbol jerárquico de clases se agregan implementaciones vacías de una interfaz ya existente.

Es fácil demostrar esto, supongamos que se tiene un árbol jerárquico m’, con un valor de la métrica V-DIN0 como sigue:

V-DINO(m’) = NFNO’ / (C-NOC x NFV), y que se modifica al árbol m’ agregando implementaciones vacías, lo cual genera el árbol m”, con un valor de la métrica V-DIN0 como sigue:

V-DINO(m”) = NFNO” / (C-NOC x NFV), donde se tiene que NFNO” > NFNO’ porque aumentaron las funciones que no se ocupan.

Comparando ambos valores de la métrica para m’ y m”, como los denominadores son iguales, se tiene que:

NFNO’ < NFNO” => V-DINO(m’) < V-DINO(m”) y queda demostrado que V-DiNO(m”) no disminuye con respecto a V-DINO(m’) cuando se agregan relaciones a my’.

Propiedad 4 de Cohesión: M6dulos Cohesivos La propiedad especifica que la cohesión de un módulo generado por la fusión de dos módulos no debe aumentar con respecto al máximo valor de cohesión de los dos módulos por separado, siempre y cuando estos módulos no tengan relaciones entre ellos.

Traducido para el caso de la métrica V-DINO, se dirá que el valor de la métrica para un árbol jerárquico formado por la unión de dos árboles no debe ser mayor al máximo del valor de la métrica para esos árboles, siempre que no haya implementaciones vacías entre los dos árboles.

Para dejar lo anterior más claro, se explica el concepto de unión para árboles de clases. AI unir dos árboles lo que se tendrá es que una nueva clase abstracta tendrá las funciones virtuales puras de ambas clases abstractas que encabezaban a cada árbol, también se tiene que este nuevo árbol tendrá las clases derivadas de ambos árboles. Cada clase derivada tendrá las implementaciones con o sin código de todas las funciones virtuales puras.

Por la restricción de la propiedad, que no debe haber relaciones entre los dos árboles, se considera que no habrá implementaciones vacías entre las clases derivadas de un árbol con las funciones virtuales puras del otro árbol. Esto es muy raro y poco probable que suceda en la realidad, pero la demostración debe hacerse bajo esta condición.

Entonces se considera que existen dos árboles jerárquicos mi y m2 parte del mismo sistema MS, es decir ml G MS y m2 c MS, donde

V-DINO(m1) = NFNOI / (C-NOCl x NFVI), V-DINO(m2) = NFNO2 / (C-NOCi x NFV2).

85

Page 108: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo A. V-DIN0 corno Métrica de Cohesión

Ahora se generará un nuevo árbol m’ el cual será la unión de los árboles m i y m2, es decir: m’ = mi u m2. E1 valor de la métrica V-DINO para este árbol es

donde: V-DINO(m’) = NFNO’ / (C-NOC’ x NFV’),

NFNO’ = NFNOi U NFNOz = NFNOi + NFN02 - NFNOco,,,,, , C-NOC’ = C-NOCi U C-NOC2 = C-NOCI + C-NOC2 - C-NOCcomunes y NFV’ = NFVi U NFV2 = NFVi + NFV2 - NFVc,mun,s .

Esto es, si los árboles mi y m2 tenían interfaces o clases derivadas comunes, estas no estarán repetidas en m’. Para el peor de los casos en donde los árboles no tengan interfaces y clases derivadas comunes, simplemente se tiene que NFNO’ = NFNOl + NFN02, C-NOC’ = C-NOCi + C-NOCz y NFV’ = NFVi + NFVi .

Si se sustituyen estos términos en la fórmula de V-DIN0 para m’, y después de hacer las operaciones correspondientes, se tiene

NFNq + NFNQ (c - N O G X N F ~ ) + (c- NO+NFV) + (c - NOC;~NF&) + (c - NOC;XNF&)

V - DINO=

Como se puede observar, el denominador crece con respecto a los denominadores de cada árbol, también lo hace el numerador, pero se sabe por la propiedad 1 de la cohesión que el aumento del numerador no será mayor al aumento del denominador, por eso se puede considerar que

max { V-DINO(ml), V-DINO(m2) } 2 V-DINO(m’).

Para cerciorarse que son correctas estas demostraciones, se tomaron los MAOO’s de prueba del Capítulo 6 , y en todos los casos se pudo verificar que fue correcta la interpretación de V-DIN0 como métrica de cohesión.

86

Page 109: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo B. V-DIN0 wmo Escala Ordinal

Anexo B) V-DIN0 COMO ESCALA ORDINAL

Escala Ordinal

La escala ordinal va más allá de la escala nominal, la cual sólo sirve para determinar si un objeto es igual o diferente a otro, colocándoles un identificador.

En este anexo se demuestra como la métrica propuesta V-DNO cumple las condiciones de la escala ordinal, la cual establece un orden entre los objetos medidos.

Definición de Escala Ordinal (Zuse981 Supongamos que (P,*>) es un sistema relaciona1 empírico, donde P es un conjunto contable no vacío de diagramas de flujo y donde -2 es una relación binaria en P. Luego existe una función u: P -> 9i, con

para todo PI , P2 E P, sí y sólo sí -2 es un orden débil. Si tal función u existe, entonces

es una escala ordinal.

P1 '> P2 0 u(P1) 2 u(P2),

((P,*2),(91, ?),U)

87

Page 110: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo B. V-DIN0 a m o Escala Ordinal

Para el caso de la métrica V-DINO, u, se supondrá que P es el conjunto de árboles de clases o jerarquías de herencia que inician con una clase abstracta, % es el conjunto de números reales, los cuales sólo estarán en el rango O - 1 debido a la normalización de la métrica, ‘1 es una relación empírica entre árboles de clases que describe que una jerarquía de clases tiene mayor o igual grado de dependencia de interfaces debido a interfaces no utilizadas y 1 es el operador normal “mayor o igual que” para comparar números.

En términos más sencillos, la escala ordinal ( (P, i ) , (%, ?),V-DINO) nos indica que cada árbol de clases formado a partir de una clase abstracta tendrá un número real asignado a él, el cual será el valor de la métrica V-DINO, y si un árbol de clases tiene más dependencia de interfaces que otro árbol esto se verá reflejado en los números que representan y fueron asignados a ambos árboles.

Definición de Orden Dkbil [Zuse98] Para poder describir a la métrica V-DIN0 como una escala ordinal, se debe comprobar que la relación *> es un orden débil, es decir, es una relación binaria que es transitiva y completa:

PI ‘2 P2, y P2 e P3 =>PI ‘1 P3 Transitiva P1 . > P 2 ó P 2 * > P I Completa

para todo P1, P2 y P3 E P, donde 01 es una relación empírica binaria, como igual o más dificil de mantener.

Demostración

La escala ordinal es la base de la medición, todas las otras escalas están basadas en ella. De la escala nominal sólo toma la condición de que los conceptos medidos pueden ser iguales o diferentes.

Si se desea utilizar una métrica en el nivel de escala ordinal, entonces se tienen que cumplir en la realidad las condiciones empíricas de que establezca una relación transitiva y completa. Ambas condiciones son condiciones empíricas, pero son derivadas de las propiedades numéricas de los números reales.

Es fácil observar que si 8 > 5 y 5 > 2 entonces 8 > 2. Esto es una propiedad muy conocida de los números reales. Si se quiere mapear propiedades empíricas hacia números reales entonces se necesita de las propiedades de ser transitiva y completa como condiciones empíricas.

Relación Transitiva Si -1 es la relación empírica “igual o con mayor grado de dependencia de interfaces”, entonces una relación transitiva significa que: si PI tiene mayor grado de dependencia de interfaces que P2; y P2 tiene mayor grado de dependencia de interfaces que P3; implica que PI tiene mayor grado de dependencia de interfaces que P3. Esto se escribe:

PI -1 P2, y P2 ‘1 P3 => PI ‘2 P3

88

Page 111: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo B. V-DIN0 como Escala Ordinal

Si se combina esta propiedad empírica con la propiedad de ser transitivos de los números, entonces se tendría que:

PI -2 P2, y P2 '> P3 => PI '> P3 @

V-DRúO(P 1)>V-DINO(P2), V-DINO(P2)>V-DINO(P3) => V-DRúO(Pl)>V-DINO(P3)

Como se pudo observar en los casos de prueba, esta propiedad se cumplió para los MAOO's analizados. Por ejemplo, el árbol de la clase CStrategy de la Figura 36 tiene mayor dependencia de interfaces, debido a la cantidad de interfaces no utilizadas, que el árbol de la clase CLista de la Figura 34. Este último árbol a su vez tiene mayor grado de dependencia de interfaces que el árbol de la clase aED de la Figura 36, el cual ni siquiera cuenta con el problema.

Reflejado en números se tiene que: CStrategy *> CLista, y CLista -2 aED => CStrategy *> aED

cs 0.6120 > 0.5000, y 0.5000 > 0.0000 => 0.6120 > 0.0000

Relación Completa Si se tienen P1 y P2, se debe poder decir que P1 tiene mayor o igual grado de dependencia de interfaces que P2, o viceversa. Esto se escribe como:

P l 'LP2óP2 .>P l

Utilizando la métrica V-DIN0 y comparando las estnicturas de clases con irnplementaciones vacías de interfaces, en los casos de prueba siempre fue posible determinar cuando existía mayor o menor grado de dependencia de un árbol con otro árbol.

Orden de Clasificación La tercera condición para una escala ordinal es el homomorfismo entre los sistemas relacionales empírico y numérico por el orden de los objetos. Esto se denota como:

P1 ' L P2 @ u(P1) > u(P2)

El orden creado pcr la métrica V-DIN0 debe ser el mismo que el orden creado empíricamente mediante experimentación. O viceversa, si se ordenan a los árboles de clases de una forma, la métrica V-DIN0 debe crear el mismo orden,

Esto se puede observar en los datos contenidos en la Tabla 2, donde se considera que entre baya más clases derivadas con implementaciones vacías, más crece el problema, si se considera al caso más común del problema de dependencia de interfaces. Y este mismo comportamiento se observa en los valores de la métrica V-DINO, en donde también va creciendo el grado de dependencia de interfaces. Esto es:

(6 Clases) -2 (5 Clases) -2 (4 Clases) *> (3 Clases) -2 (2 Clases) Q

0.8333 > 0.8000 > 0.7500 2 0.6666 2 0.5000

89

Page 112: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

Anexo C) ANÁLISIS DEL SISTEMA

Explicación de Actores

Usuario Representa una persona o sistema externo que utiliza la herramienta. Tiene básicamente tres acciones que puede ejecutar: Seleccionar archivos para analizarlos, ejecutando el caso de uso Manejar Archivo, solicitar el cálculo de la métrica V-DINO, ejecutando el caso de uso Métrica, y solicitar la ejecución del método de refactorización denominado “Separación de Interfaces”, ejecutando el caso de uso Generar Arquitectura.

Interviene en otras opciones y datos de entrada en los diferentes casos de uso, pero esto es explicado en los flujos donde ocurren estas intervenciones.

Archivo Original Representa a los archivos .h, .hpp, .c y .cpp que el Usuario elige abrir en el caso de uso Manejar Archivo. Son los archivos donde se encuentra.el código que se desea analizar. Estos archivos serán modificados si se elige ejecutar el caso de uso Generar Arquiieciura y eventualmente se convertirán en los Archivos Finales.

90

Page 113: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

Archivo Fuente Representa a los archivos .h, .hpp, .c y .cpp que el Usuario elige crear como respaldo en el caso de uso Manejar Archivo. Estos archivos son una copia del código original del M A 0 0 a analizar, y no serán modificados. Sólo quedan para respaldo del Usuario para regresar a la versión anterior del MAOO.

Archivo Final Representa a los archivos .h, .hpp, .c y .cpp que los casos de uso Generar Arquitectura y Generar Codigo producen como salida. Estos archivos tienen el código refactorizado después de ejecutar el método de refactorización. Si se aplicara sobre este código otra vez el método, no debería de producirse ningún cambio.

Base de Datos Representa la base de datos donde será almacenada la información producida por el caso de uso Análisis Sintáctico, que será utilizada por los casos de uso Métrica, Generar Arquitectura y Generar Cedigo. Su modelo entidad-relación se muestra en la Figura 25.

Flujo de Eventos para el Caso de Uso Manejar Archivo (Figura 11)

Condiciones Previas No hay condiciones previas para este caso de uso. Este caso se tiene que ejecutar antes que los demás casos de uso.

Flujo Principal Este caso de uso empieza cuando el Usuario entra al sistema y elige la opción de Seleccionar Archivos Originales. El sistema entonces muestra el cuadro de diálogo Abrir Archivos. Se presenta al usuario la opción de abrir uno o más archivos, y si esta opción tiene éxito se presenta entonces la opción de crear copias de seguridad. También se puede elegir la opción de cancelar del cuadro de diálogo (E- I).

Si la actividad seleccionada es abrir uno o más archivos, el subflujo S-1: Seleccionar Archivo es ejecutado.

Si la actividad seleccionada es crear copias de seguridad, el subflujo S-2: Crear Copia de Archivo es ejecutado.

Si la actividad seleccionada es cancelar, termina el caso de uso.

Subflujos S-1: Seleccionar Archivo. El sistema despliega el cuadro de diálogo Abrir Archivos, que permite seleccionar un directorio dentro de las unidades de la computadora local y dentro de él se pueden seleccionar uno o más archivos .h, .hpp, .c Ó .cpp que identifican a los archivos de C++ que el Usuario quiere que sean analizados. También se puede escribir éI(1os) nombre(s) de archivo(s) en el cuadro de edición. Una vez seleccionados o escritos los archivos, se presiona la opción de Aceptar (E-I). En dado caso que no haya errores se procede al subflujo S-2, quedando activos en el sistema estos Archivos Originales seleccionados.

91

Page 114: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

S-2: Crear Copia de Archivo. El sistema muestra un cuadro de decisión en donde se pregunta al usuario si desea hacer copias de seguridad de los Archivos Origin&. Las opciones son SI y NO (E-2). En caso afirmativo, el sistema crea un directorio llamado Fuente (E-3, E-4), anidado dentro del directorio que seleccionó el Usuario en S-I. En este nuevo directorio se crea una copia de todos los Archivos Originales que fueron seleccionados en S-1(E-5, E-6). Estas copias pasan a ser los Archivos Fuente activos en el sistema.

Flujos Alternos E-1: Se introdujo un nombre de archivo inválido, no se puede abrir el archivo o no se eligió ningún archivo. Se informa al Usuario de este error y el cuadro de diálogo se cierra. Quedan activos los archivos que hayan sido previamente seleccionados en otra ejecución del caso de uso, si es que había alguno. El error se produce porque los archivos no existen o están dañados. Termina el caso de uso.

E-2: El Usuario elige la opción NO. En este caso no quedan Archivos Fuente activos en el sistema. Termina el caso de uso.

'

E-3: Un directorio llamado Fuente ya existe. Si esta es la opción, no se crea un nuevo directorio, y se utiliza el ya existente. El caso de uso continúa.

E-4: El sistema no pudo crear el directorio Fuente, Se informa de este error al usuario, indicando que no se pudieron crear las copias de seguridad. En este caso no quedan Archivos Fuente activos en el sistema. Este error se puede producir si la unidad en donde se quiere crear el directorio es de sólo lectura o está protegida contra escritura. El caso de uso termina.

E-5: Un archivo con el mismo nombre ya existe en el directorio. El archivo anterior es sobrescrito de manera automática (E-6). El caso de uso continúa.

E-6: El sistema no puede copiar o sobrescribir el archivo. Se informa de este error al usuario, indicando que no se pudieron crear las copias de seguridad. En este caso no quedan Archivos Fuente activos en el sistema. Este error se puede producir si la unidad en donde se quiere copiar el archivo es de sólo lectura, no tiene espacio libre o está protegida contra escritura. El caso de uso termina.

Flujo de Eventos para el Caso de Uso Análisis Sintúctico (Figura 12)

Condiciones Previas El subflujo Seleccionar Archivo del caso de uso Manejar Archivo debe de ejecutarse antes de este caso de uso. Esto es porque debe de haber archivos originales activos en el sistema, para que este caso de uso trabaje sobre ellos.

Flujo Principal Este caso de uso empieza cuando el caso de uso Métrica o el caso de uso Generar Arquifectura lo solicitan. Se utilizará un analizador sintáctico para recorrer todos los

92

Page 115: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

Archivos Originales, buscando los datos necesarios para la reestructura del código para almacenarlos en la Base de Datos. Las actividades que se realizan son las de encontrar las clases abstractas, encontrar las clases derivadas y encontrar las funciones con implementación vacía. Estas actividades son llevadas a cabo de forma secuencial.

Si la actividad a realizar es encontrar las clases abstractas, el subflujo S-2: Encontrar Clase Abstracta es ejecutado. Para llevar a cabo esto se ejecuta también el subflujo S-I: Encontrar Función Virtual Pura.

Si la actividad a realizar es encontrar las clases derivadas, el subflujo S-3: Determinar Clase Derivada es ejecutado.

Si la actividad a realizar es encontrar las funciones con implementación vacía, el subflujo S-4: Encontrar Función Vacía es ejecutado.

Subflujos S-1: Encontrar Función Virtual Pura. El analizador sintáctico, de manera transparente al Usuario, recorrerá todos los Archivos Originales .h y .hpp que estén activos. Lo que se busca es la declaración de funciones virtuales puras, es decir, funciones igualadas a cero (E-I). Se crea un registro en la tabla FVP de la Base de Datos para registrar en el campo idFVP un número identificador de la función virtual, asignado automáticamente, en el campo nombreFVP el nombre de la función, en el campo retorno el tipo de dato de retorno y en el campo linea el número de línea en donde está declarada la función dentro del archivo. Por cada parámetro de entrada que tenga la función virtual pura se crea un registro en la tabla PARAM (E-3), colocando en el campo idFVP el número identificador de la función virtual, para ligar los registros, en el campo tipoPARAM el tipo de dato del parámetro, en el campo nombrePARAM el nombre de la variable de entrada, en el campo apuntador se coloca un SI o NO, dependiendo si el parámetro es un apuntador o no, y en el campo valorPARAM el valor por defecto que tenga el parámetro (E-4). El caso de uso continúa.

S-2: Encontrar Clase Abstracta. El analizador sintáctico, de manera transparente al Usuario, recorrerá todos los Archivos Originales .h y .hpp que estén activos. Para encontrar las clases abstractas primero se ejecuta el subflujo S-I, ya que una clase abstracta es aquella que tiene una o más funciones virtuales puras. Una vez concluido este caso se crea un registro en la tabla CA de la Base de Datos por cada clase que tenga una o más funciones virtuales puras (E-5), para registrar en el campo idCA un número identificador de la clase, asignado automáticamente, en el campo nombreCA el nombre de la clase, en el campo archivoH el nombre del Archivo Original .h o .hpp que contiene la declaración de la clase, y en el campo archivoC el nombre del Archivo Original .c o .cpp que contiene la implementación de la clase. Aparte en el campo idCA del registro de la función virtual pura creado en la tabla FVP se pone también el número identificador de la clase abstracta para ligar ambos registros. El caso de uso continúa.

S-3: Determinar Clase Derivada. El analizador sintáctico, de manera transparente al Usuario, recorrerá todos los Archivos Originales .h y .hpp que estén activos. Para encontrar las clases derivadas de

93

Page 116: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

clases abstractas primero se ejecuta el subflujo S-2, ya que una clase derivada es aquella que hereda de una clase abstracta. Se crea un registro en la tabla CD de la Base de Datos por cada clase que hereda de una clase abstracta registrada previamente en $2. En el campo idCD se registra un número identificador de la clase derivada, asignado automáticamente, en el campo nombreCD el nombre de la clase, en el campo idCA el número identificador de la clase abstracta, para ligar este registro de la tabla CD con el de la tabla CA, en el campo archivoH el nombre del Archivo Original .h o .hpp que contiene la declaración de la clase, en el campo archivoC el nombre del Archivo Original .c o .cpp que contiene la implementación de la clase, en el campo lineaD el número de línea en donde está la relación de herencia, y en el campo lineal el número de línea donde está la directiva #include de la clase abstracta en el archivo .h o .hpp. El caso de uso continúa.

S-4: Encontrar Función Vacía. El analizador sintáctico, de manera transparente al Usuario, recorrerá todos los Archivos Originales .c y .cpp que estén activos. Para encontrar las funciones con implementación vacía primero se ejecutan los subflujos anteriores, para tener la información referente a las funciones virtuales, y a las clases abstractas y derivadas. Dentro de la implementación de las clases derivadas se debe de buscar la implementación de cada función virtual que tenga su clase base abstracta, para así determinar si esta implementación está vacía o no. Se considera vacía cuando una función que no tiene valor de retorno sólo tienes las llaves de apertura y cierre, o cuando una función que si tiene valor de retorno regresa un valor nulo (E-6). Por cada función virtual implementada en una clase derivada se crea un registro en la tabla ZMPLE de la Base de Datos (E-7), en el campo idFVP se registra el número identificador de la función virtual pura, para ligarlo con el registro correspondiente de la tabla FVP, en el campo idCD el número de identificador de la clase derivada, para ligarlo con el registro correspondiente de la tabla CD, en el campo vacía se coloca un SI o NO, dependiendo de si la implementación se considera vacía o no, en el campo archivo el nombre del Archivo Original .c o .cpp que tiene la función, en el campo línea el número de línea en donde está declarada la función en el archivo de cabecera, en el campo lineal el número de línea donde empieza la implementación de la función, y en el campo linea2 el número de línea donde termina la implementación de la función. Adicionalmente se tiene que revisar en todos los Archivos Originales las llamadas a las funciones antes encontradas, ya sean vacías o no. Por cada llamada que se encuentre se crea un registro en la tabla LLAM, en el campo idFVP se registra el número de identificador de la función virtual, para ligarlo con el registro de la función, en el campo linea va el número de línea en donde está la llamada a la función, y en el campo archivo el nombre del archivo donde se encontró la llamada. Termina el caso de uso.

Flujos Alternos E-1: No se encontraron funciones virtuales puras. S e buscarán Únicamente funciones virtuales que no estén implementadas en la misma clase (E-2), y a estas funciones se les considerará como funciones virtuales puras. El caso de uso continúa. E-2: No se encontraron funciones virtuales ni virtuales puras. Cuando tampoco se puede cumplir la condición de E-1, se toma entonces que no existen funciones virtuales puras, por ende no hay clases abstractas ni derivadas de éstas. Termina el caso de uso.

94

Page 117: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

E-3: La función virtual pura no tiene parámetros de entrada. En este caso no se crean registros en la tabla PARAM, pero esto no afecta a la correcta ejecución del caso de uso. El caso de uso continúa.

E-4: El parámetro no tiene valor por defecto. En este caso la Base de Datos permite que el campo quede vacío. El caso de uso continúa.

E-5: Una clase tiene más de una función virtual pura. Aquí se debe verificar que antes de crear un nuevo registro, el valor de nombreCA no exista’ya en otro registro, y si ya existe no se crea el registro. Con esto se evita tener duplicados del mismo registro. El caso de uso continúa.

E-6: Valores nulos de retorno. Para considerar que una función regresó un valor nulo, sólo se buscará que esa función tenga una sola línea de código “return O;” para valores de retorno numéricos, “return null;’’ para valores de retorno de objetos o cadenas, y “return ”;” para valores de retorno de caracteres. Si por alguna razón la función tiene código diferente a éste, el analizador sintáctico tomará a la función como necesaria, aunque la función en realidad no sea necesaria. El caso de uso continúa.

E-7: Una clase derivada no tiene implementada a una función virtual pura de su clase abstracta. Este caso sólo se puede dar si antes se entró al flujo alterno E-1. Lo que se hace es hacer un registro de esta función colocándola como vacía, poniendo valores ‘O’ en los campos linea, lineal y lineal. Se necesitan estos registros vacíos para el caso de uso Métrica. El caso de uso continúa.

Flujo de Eventos para el Caso de Uso Métrka (Figura 13)

Condiciones Previas El caso de uso Análisis Sinfúctico debe de ejecutarse antes de este caso de uso, y es llamado automáticamente por Métrica. Esto es porque debe de estar llena la Base de Datos antes de realizar el cálculo de la métrica de este caso de uso.

Flujo Principal Este caso de uso empieza cuando el Usuario elige la opción Calcular Métrica V-DIN0 del menú principal del sistema. Este caso de uso realiza dos actividades en forma secuencial, primero se hace el cálculo de la métrica y posteriormente se regresa al Usuario el valor calculado, con la correspondiente interpretación del resultado.

Si la actividad a realizar es el cálculo de la métrica, el subflujo S-1: Calcular V- DIN0 es ejecutado.

Si la actividad a realizar es la interpretación del resultado, el subflujo S-2: Interpretar Resultado es ejecutado.

Subflujos S-1: Calcular V-DINO.

95

Page 118: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

Para calcular la métrica V-DINO de Dependencia de Interfaces que No se Ocupan Únicamente se toman datos de la Base de Datos. El proceso se realiza tantas veces como registros haya en la tabla CA (E-1). Por cada registro de clase abstracta, se tiene que determinar cuantas ciases derivadas tiene, es decir, clases que hereden de esa clase abstracta, utilizando la tabla CD y buscando que el campo idCA sea igual al del registro de la clase abstracta; también se determina cuantas funciones virtuales puras tiene la clase abstracta, buscando en la tabla FVP que el campo idCA sea igual al del registro de la tabla CA; y el tercer dato que se ocupa es el número de funciones implementadas vacías, utilizando la tabla IMPLE y el campo idFVP, que debe corresponder a los números de identificación de las funciones virtuales puras encontrados para el segundo dato, y con esto se hace el conteo de las funciones vacías (E-2). El valor de la métrica es el número de funciones vacías entre la multiplicación del número de clases derivadas por el número de funciones virtuales puras, y este valor se presenta al Usuario. El caso de uso continúa.

S-2: interpretar Resultado. Cuando se hace el cálculo de V-DIN0 para una clase abstracta en S-1 se procede a interpretar ese valor. En caso que el valor sea de 0.500 o mayor, se recomendará al Usuario que proceda a resolver el problema de dependencia de interfaces, utilizando el método de Separación de Interfaces. En caso que el valor de V-DIN0 sea menor a 0.500 (E-3), entonces se recomendará al usuario que no hay necesidad de ejecutar el método de refactorización. Dependiendo de la decisión del Usuario, se ejecuta el caso de USO Generar Arquitectura (E-4). Termina el caso de uso.

Flujos Alternos. E-1: La tabla CA no tiene registros. Este caso se da sólo cuando se ejecuta el flujo alterno E-2 del caso de uso Análisis Sinfácfico. En este caso no se puede calcular el valor de V-DiNO, por tanto se informa de esto al Usuario, y se le dice que no tiene porqué ejecutar el método de refactorización, ya que no hará nada por no existir clases abstractas ni funciones virtuales puras. Termina el caso de uso.

E-2: Hay registros con campos nulos en IMPLE. Esto sucede sólo cuando se ejecuta el flujo alterno E-1 del caso de uso Analisis Sintáctico. Este caso no afecta al cálculo de la métrica ni a su interpretación, pero el sistema debe de tener en cuenta esto si se llega a ejecutar el caso de uso Generar Arquitectura. El caso de uso continúa.

E-3: El valor de V-DIN0 es cero. Este es el único caso en donde no existe el problema, y se debe manejar un mensaje especial para el Usuario, indicando que el método de refactorización no tiene razón de ser ejecutado. El caso de uso continúa.

E-4: El Usuario no sigue la recomendación generada por medio de V-DINO. Al ejecutar el caso de uso Generar Arquitectura, no se toma en cuenta la métrica, pero es altamente probable que no se pueda resolver el problema si V-DIN0 lo indicó así. Esto no afecta el funcionamiento del método, sólo se hará trabajo extra y se conoce de antemano el resultado. El caso de uso continúa. Flujo de Eventos para el Caso de Uso Cerzerar Arquitectura (Figura 14)

96

Page 119: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

Condiciones Previas El caso de uso Análisis Sintáctico debe de ejecutarse antes de este caso de uso, y es llamado automáticamente por Generar Arquitectura si no ha sido llamado antes por el caso de uso Métrica. Esto es porque debe de estar llena la Base de Datos antes de realizar la refactorización del MAOO.

Flujo Principal Este caso de uso empieza cuando el Usuario solicita que se intente hacer la reestructura de los Archivos Originales utilizando el método de refactorización, ofrecido en la opción Método de Separación de Interfaces del menú principal del sistema. Este caso de uso tiene primeramente la función de encontrar si se puede hacer la refactorización, y para ello debe buscar interfaces afines que sean mutuamente excluyentes (E-l), y una vez encontradas éstas se procede a integrar las interfaces y ofrecer una clase intermedia por interfaz sustituida con métodos de enganche. Estas actividades se realizan en forma secuencial. El proceso se hace completo para cada clase abstracta que se tenga detectada, es decir, para cada registro de la tabla CA de la Base de Datos. Después de este caso de uso se ejecuta automáticamente el caso de uso Generar Código.

Si la actividad a realizar es buscar interfaces afines mutuamente excluyentes, el subflujo S-1: Sustituir Intecfaces es ejecutado. AI encontrar un caso de estas interfaces, se procede a integrar interfaces, ejecutando el subflujo S-2: Crear Interfaz Genérica.

Si la actividad a realizar es ofrecer clases intermedias por interfaz sustituida, el subflujo S-3: Crear Clase Intermedia es ejecutado. AI hacer una clase intermedia, se debe de agregar un método de enganche, ejecutando el subflujo S-4: Crear ‘Template Method ’.

Subflujos S-1: Sustituir Interfaces. Como se mencionó, este proceso se hace por cada registro de la tabla CA de la Base de Datos. Para cada clase abstracta, se determina que funciones virtuales implementa, utilizando la tabla FVP y el campo idCA, también se determina que clases derivadas tiene, utilizando la tabla CD y el campo idCA, y por último se encuentran todas las implementaciones de las funciones virtuales (E-2), utilizando la tabla IMPLE y los campos idFVP e idCD. AI tener recopilada esta información de la Base de Datos, se buscan interfaces afines o con la misma firma, es decir, que tengan los mismos parámetros de entrada y salida. Para esto último se utiliza la información recopilada de la tabla FVP sobre las funciones virtuales puras y la información sobre sus parámetros de salida, con el campo retorno, y sus parámetros de entrada, con la tabla PARAM y el campo idFVP. Si dos o más funciones virtuales tienen iguales estos parámetros de entrada y salida, entonces son candidatas a ser sustituidas por una interfaz genérica. Lo último que se tiene que determinar es si son mutuamente excluyentes, y para ello se tiene que determinar que una y sólo una función de las candidatas sea implementada por cada clase derivada (E-3), utilizando la información recopilada de la tabla IMPLE y el campo vacia. Cuando ya se determinó que son mutuamente excluyentes (E-l), se procede a ejecutar el subflujo S-2. El caso de uso continúa.

97

Page 120: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

S-2: Crear interfaz Genérica. Se creará una interfaz genérica que sustituya a las funciones virtuales mutuamente excluyentes encontradas en S-I. Se solicita al Usuario que proporcione el nombre que quiere para esta interfaz, ofreciendo el sistema un nombre por defecto (E-4). La función virtual pura es creada entonces en la clase abstracta (E-5), utilizando el registro de la tabla CA para colocar la información, y la información recopilada de las tablas FVP y PARAM para los parametros de entrada y salida de esta interfaz. El caso de uso continúa.

S-3: Crear Clase Intermedia. Lo que sigue es agrupar a las clases derivadas por la única función virtual que implementan, del grupo de funciones virtuales puras mutuamente excluyentes encontradas en S- l . Al tener esta agrupación, utilizando la información recopilada de la tabla ZMPLE, se procede a crear una clase genérica para cada grupo que haya surgido. Se solicita al Usuario que proporcione el nombre que quiere para cada clase intermedia, y para los nombres de los archivos .h y .cpp que se crearán para esta clase, ofreciendo el sistema un valor por defecto (E-6). Entonces se crean los nuevos archivos en el mismo directorio donde están los Archivos Originales (E-7) y se llenan con la información que ya se tiene recopilada, como es la herencia hacia la clase abstracta y nombre de la clase intermedia, así como el esqueleto de la declaración e implementación (E-8). Se les tiene que crear un método de enganche, para conectarse con las clases derivadas de su grupo, y para ello se ejecuwei subflujo S-4. El caso de uso continúa.

S-4: Crear ‘Template Method’. Un ‘Template Method’ es un método de enganche que servirá para conectar la nueva función virtual pura creada en la clase abstracta, con la implementación realizada en las clases derivadas. En este proceso sólo se hace la declaración del método en el archivo .h recién creado y el esqueleto de la función en el nuevo archivo .cpp de la clase intermedia (E-8), es decir sólo se coloca la línea de identificación de la función y las llaves de apertura y cierre. Todos los datos para este método ya se tienen recopilados. Termina el caso de uso.

Flujos Alternas E-1: No se encontraron funciones virtuales puras mutuamente excluyentes. En este caso no se puede hacer la separación de interfaces. Se informa de esto al Usuario indicando sobre que clase abstracta no se puede ejecutar el método. El caso de uso termina para esa clase abstracta, se procede con la siguiente.

E-2: Se tienen registros de la tabla IMPLE con campos línea, lineal y linea2 iguales a cero. Este caso se da sólo cuando se ejecutó el flujo alterno E-1 del caso de uso Análisis Sintáctico. Estos registros no deben ser tomados en cuenta para la recopilación de información. El caso de uso continúa.

E-3: De un grupo de funciones candidatas sólo algunas son mutuamente excluyentes. En este caso se tendrá que preguntar al Usuario que acción tomar, si sólo sustituir algunas o no modificar nada. Dependiendo de la respuesta del Usuario el caso de uso continúa o termina.

98

Page 121: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

E-4: El nombre de la función virtual pura ya está siendo utilizado o no es válido. ES una de las precondiciones del método de refactorización, al encontrar nombres repetidos, se debe solicitar de nuevo al usuario^ un nombre, indicando que el anterior no puede ser usado. El caso de uso continúa.

E-5: Esta activada la bandera que indica que el flujo alterno E-I del caso de uso Análisis Sintúctico fue ejecutado. En este caso no se debe crear una función virtual pura sino sólo una función virtual sin implementación en la clase abstracta. El caso de USO continua.

E-6: El nombre de la clase intermedia o de los archivos ya está siendo utilizado o no es válido. Es una de las precondiciones del método de refactorización, al encontrar nombres repetidos, se debe solicitar de nuevo al Usuario un nombre, indicando que el anterior no puede ser usado. El caso de uso continúa.

E-7: No se pueden crear los nuevos archivos. Esto se puede dar si el directorio está dentro de una unidad de sólo lectura o si está protegida contra escritura. Se debe dar un mensaje de error al Usuario con la opción de reintentar. Si otra vez no se puede realizar la operación se debe cancelar todo el proceso y el caso de uso termina, en caso que si se efectúe la operación, el caso de uso continúa.

E-8: No se pueden modificar los Archivos Originales. Esto se puede dar si el directorio está dentro de una unidad de sólo lectura o sí está protegida contra escritura. Se debe dar un mensaje de error al Usuario con la opción de reintentar. Si otra vez no se puede realizar la operación se debe cancelar todo el proceso y el caso de uso termina, en caso que si se efectúe la operación, el caso de uso continúa.

Flujo de Eventos para el Caso de Uso Generar Código (Figura 15)

Condiciones Previas El caso de uso Generar Arquitectura debe de ejecutarse con éxito antes de este caso de uso. Esto es porque ya debe de haber clases intermedias para separar las interfaces.

Flujo Principal Este caso de uso empieza cuando el caso de uso Generar Arquitectura lo invoca automáticamente. Tiene la función de refactorizar todo el código con el nuevo diseño generado por el caso de uso Generar Arquitectura para que siga teniendo la misma funcionalidad del M A 0 0 original. Este proceso, al igual que en el caso de uso anterior, se lleva a cabo por cada clase abstracta que tuvo funciones virtuales puras mutuamente excluyentes. Las actividades de este caso se realizan en forma secuencial. Primeramente se deben reubicar las funciones virtuales puras, implementando los ‘Template Methods’; después se cambian las relaciones de herencia, modificando las directivas #include; posteriormente se eliminan las funciones con implementación vacía que fueron sustituidas, eliminando con ello sus declaraciones; y por último se modifican las llamadas a las funciones que fueron sustituidas.

99

Page 122: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

Si la actividad a realizar es reubicar las funciones virtuales puras, el subflujo S- I : Mover Función Virtud Pura es ejecutado. Y para llevar a cabo esto se ejecuta también el subflujo S-2: Implementar ‘Template Method’.

Si la actividad a realizar es cambiar las relaciones de herencia, el subflujo S-3: ModzJcar Relación de Herencia es ejecutado. Y para llevar a cabo esto se ejecuta también el subflujo S-4: Cambiar Directiva Include.

Si la actividad a realizar es eliminar las funciones vacías que si fueron sustituidas, el subflujo S-5: Eliminar Función Vacía es ejecutado. Y para llevar a cabo esto se ejecuta también el subflujo S-6: Eliminar Declaración de Función.

Si la actividad a realizar es modificar las 1lamadas.a funciones que fueron sustituidas, el subflujo S-7: Cambiar Llamada a Función es ejecutado.

Subflujos S-1: Mover Función Virtual Pura. Aquí se bajan en la jerarquía de herencia a las funciones virtuales puras mutuamente excluyentes que fueron sustituidas por una interfaz genérica. Cada una de las funciones virtuales se baja de la clase abstracta hacia una de las clases intermedias que fueron creadas en el caso de uso Generar Arquitectura, donde la clase intermedia será la base para el grupo de clases derivadas que implementan esa función virtual pura. Esto implica borrar la función de la clase abstracta, utilizando los datos recopilados de la tabla CA y FVP de la Base de Datos, y agregarla en la clase intermedia, utilizando la información generada en el caso de uso previo. Aquí se modifican los Archivos Originales .h de la clase abstracta e intermedia (E-1). Después de hacer esto para cada clase intermedia, se debe ejecutar el subflujo S-2. Después de borrar las funciones virtuales puras innecesarias de la clase abstracta, sus archivos ya no sufrirán más modificaciones (E-2), salvo que los modifique S-7 para cambiar llamadas a funciones. El caso de uso continúa.

S-2: Implementar ‘Template Method’. Los ‘Template Methods’ ya habían sido creados y declarados en el subflujo S-4 del caso de uso Generar Arquitectura. Ahora se modificará el aichivo donde se encuentra la implementación del ‘Template Method’ (E-]). La implementación del método será una sola línea con una llamada hacia la función virtual pura, pasándole sus parámetros de entrada (E-3). Después de realizar esto, los archivos de las clases intermedias ya no ocupan más modificaciones, salvo que los modifique S-7 para cambiar llamadas a funciones. El caso de uso continúa.

S-3: Modificar Relación de Herencia. Este proceso es para cambiar las relaciones de herencia de las clases derivadas que fueron agrupadas en el subflujo S-3 del caso de uso Generar Arquitectura, cambiando la herencia de la clase abstracta hacia la clase intermedia que encabeza el grupo. Para ello se toma la información recopilada de la tabla CD, en especial del campo IineaD, colocando ahora el nombre de la clase intermedia correspondiente. Se hace la modificación en el archivo .h o .hpp de la clase derivada, referenciado por el campo archivoH de la tabla CD (E-]). Después de cambiar esta línea, se ejecuta el subflujo S- 4. EI caso de uso continúa.

100

Page 123: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

S-4: Cambiar Directiva Include. Una vez que se cambió la relación de herencia lo que sigue es cambiar la directiva #include. En esa instrucción se pondrá el nombre del archivo .h o .hpp que tiene la declaración de la clase intermedia correspondiente. La ubicación de esta línea se tiene almacenada en el campo lineal del registro de la clase derivada en la tabla CD, indicando la ubicación dentro del archivo .h (E-I). Hay que recordar que el archivo en sí está referenciado por el campo archivoH de la tabla CD. El caso de uso continúa.

S-5: Eliminar Función Vacía. Este proceso ocurre en los archivos .c o .cpp de las clases derivadas, apuntados por el campo archivoC de la tabla CD (E-1). Lo que se hace es eliminar la implementación de las funciones virtuales que no ocupa esa clase derivada, ya que sólo ocupa una función virtual del grupo de funciones mutuamente excluyentes, determinada en el subflujo S-3 del caso de uso Generar Arquitectura. Para borrar estas implementaciones se toma la información de su ubicación de los campos lineal y linea2 del registro de la implementación de función en la tabla IMPLE (E-4). Una vez eliminado este código del Archivo Original, se procede a ejecutar el subflujo S-6. El caso de uso continúa.

S-6: Eliminar Declaración de Función. Este proceso ocurre en los archivos .h o .hpp de las clases derivadas, apuntados por el campo archivoH de la tabla CD (E-1). Lo que se hace es eliminar la declaración de la función virtual que no ocupa esta clase derivada, cuya implementación ya fue borrada en S-5. Para borrar esta declaración se toma la información sobre su ubicación del campo línea del registro de la función en la tabla IMPLE (E-4). Después de esto, los archivos de las clases derivadas ya no ocuparán más modificaciones, salvo que los modifique S-7 para cambiar llamadas a funciones. El caso de uso continúa.

S-7: Cambiar Llamada a Función. Este proceso puede ocurrir en cualquier Archivo Original. Lo que se hace es cambiar los nombres de funciones sustituidas en las llamadas registradas en la tabla LLAM. Se sustituye el nombre de la función virtual original por el nombre de la interfaz genérica. No hay necesidad de cambiar nada más, ya que ambas funciones tienen los mismos parámetros de entrada y salida. Termina el caso de uso.

Flujos Alternos. E-1: No se pueden modificar los Archivos Originales. Esto se puede dar si el directorio está dentro de una unidad de sólo lectura o si está protegida contra escritura. Se debe dar un mensaje de error al Usuario con la opción de reintentar. Si otra vez no se puede realizar la operación se debe cancelar todo el proceso y el caso de uso termina, en caso que si se efectúe la operación, el caso de uso continúa.

E-2: Las funciones virtuales eliminadas de la clase abstracta no son puras. Esto sucede cuando se ejecutó el flujo alterno E-I del caso de uso Análisis Sinfáciico. En este caso también se debe buscar dentro del archivo .c o .cpp de la clase abstracta la implementación vacía de esta función, para eliminarla. Este archivo está referenciado por el campo archivoC de la tabla CA. El caso de uso continúa.

101

Page 124: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo C. Análisis del Sistema

E-3: La función virtual pura tiene valor de retorno. Sucede cuando el campo retorno del registro de la función en la tabla FVP tiene un valor diferente a “void”. En este caso se debe cambiar la línea de código de irnplementación del ‘Template Method’ de una llamada hacia un regreso de valor. Y dentro de este regreso de valor con la instrucción “return” se coloca la llamada a la función. El caso de uso continúa.

E-4: La clase tiene mas de una función implementada que no ocupa. Esto no es problema, sino que se tiene que adoptar un algoritmo de borrado, eliminando la implementación o declaración que esté más abajo en el archivo, para evitar que los números de linea apuntados por línea, lineal y linea2 de los registros de la tabla IMPLE dejen de representar la ubicación de la función. El caso de uso continúa.

102

Page 125: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo D. Código del Caso de Prueba 1

Anexo D) CÓDIGO DEL CASO DE PRUEBA 1

Código Original

//Parte del Código del Archivo Contexto.cpp ... void CContexto::InteractuaO (

char opcion.opcion1; CElemento *AptNodo: float ed: CLista 'List; d o í

opcion=MenuPrincipal(); switch (opcion) (

... case ' 4 ' : //Ordenar Lista

opcioni=MenuOrdenacion(~ : switch (opcionll [

case ,l': //Metodo de la Burbuja List=new CBubbleO ; List->Ordena (this) ; break;

103

Page 126: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo D. Código del Caso de Prueba 1

1 break;

if (L->xsErnpty()==o) ( printf p\n\nLa ~ i s t a no tiene elementos") ; getchíl ; break;

case ' 5 1 : //~uccar lem mento de la Lista

I AptNodo=neu CElernentoO; printf ("\n\nrntroduzca Dato a Buscar: " I ; scanf l"%f".&edi; AptNodo->CetX (edl ; setNodoBucql*AptNodol; opcioni=MenuBucquedaO ; switch (opcioni) (

cace , I m : //Metodo de Busqueda Secuencia1 List=new CSecuenc 1 ) i List->Busqueda(thisl; break;

1 if LGetPocO ! = - l l (

printf ("\n\nElernento en la posicion $d~~.GetPosll); ) else (

printf [ "\n\nElernento No Encontrado"1 ;

getchi1 ; break;

I ) while (opcion!='o'); PantallaFinal í i ;

I ...

// Código del Archivo Lista.h #if !defined[AFX-LlCTA) #define AFX-LISTA .#include cstdi0.h;. #include "Elemento. h" #include "Contexto. h" class CElernento; class CContexto: c l a s s CLicta ( private:

CElernento *AptH: CElernento *AptT; int N;

void AnteriorlCElemento *l&nodol); void SiquienteiCElementO *(&nodoll;

public:

- int IsEmptyíi : void Borra(CElement0 *(&nodoll; void ~gregaICElemento 'nodo); CListaO; virtual -cListall: int GetNO; CElernento* GetHO ; CElernenta' GetTll: void CetNIint dato1 i void CetHICElemento *nodo); void SetTICElernento *nodal; vircualvoid OrdenaíCContexto *ctx)=O: v~rtual void Busqueda(CContext0 'Ctxl=Oi

104

Page 127: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo D. Código del Caso de Prueba 1

// Código del Archivo Bubb1e.h #if !defined(AFX-BUBBLE) #define AFX-BUBBLE #include "Li.9ta.h" class CBubble : public CLista ( public:

virtual void Ordena(CContext0 'ctx); virtual void Busqueda(CContext0 'CtX); CBubble i) ; virtual -CBubbleO;

) ; #endif

//Código del Archivo Bubble.cpp

I

#include "Bubb1e.h" CBubb1e::CBubbleil {

CBubb1e::-CBubbleO (

void CBubble::OTdena(CCOntexto 'CtXI { CElementO *AptN~dol,*AptN~doZ; int i,j.n,bandera; float x; n=ctx-sL->GetNO ; for (i=i;i<n;i++) (

bandera=O; AptNodol=ctx->L-sGetHO; AptNodoi=ctx->L->GetHO; ctx-sL-sSiguiente(AptNodo2): for lj=i;j<n;j++)(

iE ~ ~ A p t N ~ d o l - ~ G e t X O ) ~ ( A p t N o d o Z - ~ G e t X O l ~ ( bandera.1; x=AptNodol-sGetX ( ) ; AptNodol-~SetX(AptNodoZ-~GetxOl; AptNodoZ->SetX (x) ;

I ctx->L->Siguiente(AptNodol); ctx->L-sSiguienteLAptNodoZ);

1 if (bandera==O) (

//Lista Ordenada break;

I I

I I void CBUbble::BUSqUeda(CContexto *ctxj {

// Código del Archivo Secuenc.h #if !defined(AFX-SECUENC) #define AFX-SECUENC #include "Lista. h'' class CSecuenc : public CLista { public:

virtual void Ordena(CContexto *ctx): virtual void Busqueda(CC0ntexto *ctx); Csecuenc i I ; virtual -CSecuencO :

) ; #endif

// Código del Archivo Secuenc.cpp cSec"e"c::CSecuenco { #include ' 'Secuenc. h"

105

Page 128: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo D. Código del Caso de Prueba 1

1 Csecuenc::-csecuencO { I void CSecuenc::OrdenaiCContexto *ctxl { I void Csecuenc::Busqueda(CContexto 'ctxl {

CElemento *AptNOdo; CElernento nodo: int i,n. bandera=ü: double x.datoNodo; n=ctx->L->GetNO ; n ~ d o = ~ t ~ - ~ G e t N ~ d o B ~ ~ q i l : datoNodo=nodo.GetXll; AptN~do=~tx->L-zGetHiI; for (i=i;i<=n;i++>[

x=AptNodo->GetX 1 1 i if lx==datoNodol {

/ / Dato Encontrado ctx->SetPos lil ; bandera=l; break;

1 ctx-sL-iSiguienteIAptNodo1;

I

)

if (bandera==Ol [ ctx->setPosl-il;

)

Código Refactorizado

// Parte del Código del Archivo Contexto.cpp ... void CContexto::InteractuaO (

char opcion.opcion1; CElernento *AptNodo; float ed; CLista *List:

switch lopcionl (

... cace ' 4 ' : //Ordenar Lista

opcionl=Men~O~denacioniI: switch (opcionll (

case '1,: //Metodo de la Burbuja List=new CBubble í I ; L i ~ t - ~ A l g ~ ~ í t m ~ I ~ t ~ r f a l o ; break;

I break:

case ' 5 ' : //Buscar Elemento de la Lista if lL-~IsEmptyO==Ol {

printf ("\n\nLa Lista no tiene elementoc"1: getchil i break:

1 AptNado=new CElementoO: printf I"\n\nIntroduzca Dato a Buscar: " I i scanf ("%f".&ed); AptNodo-sSetXIed1 ; CetNodoBusql*AptNodo): opcionl=Men~B~~q~edaIl; Switch iopcionil[

cace '1': //~etodo de Busqueda Secuencia1

106

Page 129: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo D. Código del Caso de Prueba 1

List=new CSecuenc (I ; L i S t - z A l g O r i t m o i n t B T f e z ( t h i s ) ; break;

1 if lGetPosíi!=-l)(

printf l"\n\nElemento en la pocicion %d",GetPocO I ; 1 else (

) printf l"\n\nElemento NO Encontrado') ;

getchi) ; break;

) ) while (opcion!='O'); PantallaFinalO:

) ...

// Código del Archivo Lista.h #if IdefinedíAFX-LISTA) #define AFX-LISTA #include <atdio.h> #include "Elemento.h'r #include 'Contexto.h' class CElemento; class CContexto; class c~ista ( private:

CElemento 'AptH; CElemento 'AptT; int N;

void AnteriorlCElemento *(&nodo)); void SiguienteiCElemento *(&nodo)); int IsEmptyO ; void BorralCElemento *(&nodo)); void AgregalCElemento *nodo); CListaO; virtual -CListaO ; int GetNO ; CElemento* GetHO; CElemento' GetTO; void SetN(int dato) ; void CetHlCElemento *nodo) ; void SetT(CElement0 +nodo);

public:

/ / virtualvoid Ordena(CContext0 *ctxl=O; / / virtual void Busqueda(CC0ntexto *ctx)=o;

virtual void AlgoritmoInterfaz ( CContexto ctx j c O ; ) ; #endif

// Código del Archivo CAlgorl .h #ifndef -CAlgorl #define -CAlgorl #include "lista. bin #include "E1emento.h" #include "C0ntexto.h" class CAlgorl : public CLista ( public:

CAlgorll 1; virtual -CAlgorl( 1; virtual void BUBqlleda í CContexto * ctx I = O; void Algoritmointerfaz ( CConteXto ctx 1 1

1; 11 #endif

'! 9

107

Page 130: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo D. Código del Caso de Prueba 1

I/ Código del Archivo CAlgorl.cpp

1 1

1

#include "CAlgor1.h" CAlgorl: :CAlgOrll 1 {

CAlgorl: : -CAlgorl 1 1 (

void CAlg0rl::AlgoritmoInterfa~ I CContexto f ftx I ( Busquedalctx) ;

//Código del Archivo CAlgor2.h #ifndef -CAlgor2 #define -CAlgorZ #include "Lista.h" #include "E1emento.h" #include "C0ntexto.h" clase CAlgorZ : public CLista ( public :

CAlgorZI I ; virtual -CAlgorZ I ) i virtual void Ordena I CContexto * ctx I = O ; void Algoritmolnterfaz I CContexto ctx I ;

1; #endif

I/ Código del Archivo CAlgor2.cpp #include .CAlgorZ.h" CAlgorZ : : CAlgorZ I I { 1 1

>

CAlgor2 : : -CAlgor2 I I {

void CAlgor2::AlgoritmoInterfaz Ordenalctxl ;

( ccontaxto ctx 1 (

11 Código del Archivo Bubb1e.h #if IdefinedlAFX-BUBBLE1 #define AFX-BUBBLE #include .CAlgorZ.h" class CBubble : public CAlgorZ ( public:

/ / virtual void Bucqueda(CC0ntexto * c t x ) ; virtual void OrdenaICContexto 'ctx);

CBubble I I ; virtual -CBubble 1 ) ;

) ; #endif

/I Código del Archivo Bubbkcpp tiinclude "8ubble.h" CBubb1e::CBubbleO (

CBubble: : -Csubble I I

void CBubb1e::OrdenaíCContexto *ctxl (

( 1

CElernento *AptNOdol.*AptNodo2; int i.j,n.bandera; float x i n=ctx-sL-sGetN0; for li=i;icn;i++) (

bandera=O; AptNodol=~tx->L->GetHIl; AptN0do2=~t~-sL-,GetHI];

108

Page 131: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo D. Código del Caso de Prueba 1

ctx-sL-sSiguientelAptNodoZl; for lj=i;j<n:j++l(

if llAptNodol-~GetXlll~(APtNodo2-~G~tXllll ( bandera.1; x=AptNodol->GetXO; A p t N 0 d o l - ~ S e t X l A p t N 0 d o 2 - s G e t X o ) : AptNodo2-sSetX 1x1 ;

1 ctx->L->siguientelAptNodoll; c tx - ,L->S igu iente lAptNodo2) :

1 if (bandera==O) (

//Lista Ordenada break:

)

//void CBUbb1e::BusqUedalCContexto *Ctxl ( / I )

I! Código del Archivo Secuenc.h #if !definedlAFX-SECUENCI #define AFX-SECUENC #include "CA1gorl.h' class CSecuenc : public CAlgorl public: / / virtual void Ordena(CContexto *ctxl;

virtual void BusquedalCContexto 'ctxl; CSecuenc I 1 ; virtual -csecuencO;

1; üendif

/ I Código del Archivo Secuenc.cpp #include "Secuenc.h" csecuenc::csecuencO ( 1 csecuenc: : -CSecuenc i I 1 //void CSecuenc::oidenaiCContexto 'ctxl 111 void CSecuenc::BusquedalCContexto 'ctxl

(

CElemento 'AptNOdo; CElemento nodo; int i,n,bandera=O; double x,datoNodo; n=ctx->L->GetNO; nodo-ctx->GetNodoBusq(); datoNodo=nodo.GetX I 1 ; AptNodo=ctx-rL->GetHO; fo r li=i;ic=n;i++) (

x=AptNodo->GetX(); if lx-=datoNodo) (

/ / Dato Encontrado ctx-SetPoslil ; bandera.1; break;

I c t x - , L - > S i g u i e n t e l A p t N o d o ) ;

I

)

if lbandera==Ol ( Ctx-sSetPos 1-11 ;

1

109

Page 132: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

Anexo E) &DIGO DEL CASO DE PRUEBA 2

Código Original

// Parte del Código del Archivo Contexto.cpp ...

case '5' : //Ordenar Lista opc i~n l l l=Men~OrdenaCion( ) ; switch (opcionlll) ( case '1': //Metodo de la Burbuja

str=new CBubbleO; str->Ordena (this) ; break;

str=new CShellO; str->Ordena(thisI ; break;

cace ' 3 ' . . //Metodo de Seleccion str=new cseiec(1; str->Ordena (this1 ; break;

case ' 4 ' . . //Metodo de Insercion

case ' 2 ' : //Metodo Shell

110

Page 133: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

str=new CinsercO i str->Ordena Ithis) i break;

1 break;

I ) while (opcionll!='D');

1 ) while (opcionl!='O'); Ll=&Listal; LZ=&Lista2; L3=&Lista3; break;

case '2': //calculo de Medidas de Tendencia Central do í

opcioni=MenuTendenciaCeneral() ; switch (opcionil ( cace . //Media Aritmetica

Str=new CMediaAri I 1 ; str->Calcula(this) ; result=GetRes(l; if Iresuit==NULLl

else

getch I I ; break;

Str-new CMediaAnO ; str->Calcula(this) ; result=GetResO; if lresult==NULLl

else

printf l"\nPrimero debe introducir elementos en la Lista");

printf ("\nLa Media Aritmetica es: %lf",resultl;

cace ' 2 I : //Media Armonica

printf ("\nPrimero debe introducir elementos en la Lista"1;

printf l"\nLa Media Armonica e s : Plf".result); getchi1 ; break;

case ,3,: //Media Geometrica str=new CMediaGeoO; str->Calcula(this) ; result=GetResO; if Iresult==NULL)

else

getchili

printf ('\nPrimero debe introducir elementos en la Lista*');

printf I"\nLa Media Geometrica e s : %lf".resultl;

break; case 1 4 ' : //Media Cuadratica

Strrnew CMediaCua I 1 ; str->Calcula(this) ; reSUit=GetRes 1 ) ; if lresult==NULL)

else printf (-\nPrimero debe introducir elemento= en la Lista");

printf ("\"La Media Cuadratica e s : %lf",resultl ; getchll;

case ' 5 ' : //Mediana break;

str=new CMedianaO; str-~Calcula(thisI ;

if (TeSult=iNULL)

else

getchili

reCUlt=GetRes();

printf ("\nPrimero debe introducir elementos en la Lista"1;

printf ("\nLa Mediana es: %lf",resultI;

break;

111

Page 134: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

case '6': //Moda str=new CModa(); Ctr->Calcula(this) ; resuit=GetPa,,,,t,oiO; if (result==o) (

printf ("\nNo existe Moda. todos los datos Son diferentes o no hay datos");

1 else(

if iresult==li

) else(

1 getchi); break;

I

reSUlt=GetReSO; printf ("\nLa Moda e s : %lf".result);

printf ("\nExisten %.Oif modac",result) ;

1 ) while (opcionl!='O'); break;

...

// Código del Archivo Strategy.h #if !defined(AFX-STRATEGY) #define AFX-STRATEGY #include "Contexto.h' class CContexto; class cstrategy ( public:

CStrategyO ; virtual -Cstrategy(); virtual void CalculaiCContexto *ctx)=o; virtual void OrdenaiCContexto *ctx)=o; virtual void ResuelveiCContexto *ctx)=o; virtual double GetResultadoO=o;

1; #endif

// Código del Archivo Shel1.h #if !defined(AFX-SHELL) #define AFX-SHELL #include 'Strategy. h" class Cshell : public CStrategy { public:

virtual void Calculaiccontexto 'ctx); virtual void OrdenalCConteXtO 'ctx); virtual void ResuelveiCContexto *CtX); virtual double GetRecultadoO: Cshell O ; virtual -CShell O ;

!/ Código del Archivo Shell.cpp

)

)

1

#include "She1l.h" CShel1::CShellO (

CShel1::-CShellO (

void CShel1::CalculaíCContexto *Ctx) (

void Cshel1::OrdenaíCContexto *CtX) (

112

Page 135: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

CElemento *AptNOdol,*AptNodo2; double x; int i. j , k, 1.n. inter; n=ctx->Ll- >GetN ( I ; inter=n/2; while (inter>O) {

for ii=inter;icn;i++l( j =i-inter; while I j > - l ) (

k = j tinter; AptNodol=ctx->Li-,GetHil; AptNodo2=~tx-~L1-sGetHil; for ll=l;l~=j;l++l

for (l=l;l<=k;l++l

if ((AptNodol-zED-~GetEDOl~=(AptNodo2-~ED-zGetEDO 1 1

ctx-~Ll-~Siguiente(AptNodoll;

ctx->Ll-sSiguienteiAptNodo21;

]=.1; else(

x=AptNodol->ED-zGetED0; A p t N o d o i - ~ E D - ~ s e t E D l A p t N o d o 2 - , E D - , O e t E D O l ; AptNod02->ED-sCetED l x ) ;

) j = j -inter;

1 ) inter=inter/Z;

I 1

1

1

void CShell::ResUelVe(CContexto *ctxl (

double CShell: :GetResultadoO ( return O;

I1 Código del Archivo GaussJ0r.h #if !definediAFX-GAUSSJORI #define AFX-GAUSSJOR #include "strategy. h" class CGauSCSOr : public CStrategy ( public:

virtual void CalculalCContexto *ctxl; virtual void OrdenalCContexto *ctxI; virtual void Resuelve(CContext0 *ctxl; virtual double GetResultadoil i CGaussJor i I ; virtual -CGaussJoril;

// Código del Archivo GaussJor.cpp #include "GaussJor. h" C G ~ ~ ~ ~ J ~ r : : C G a u ~ ~ S o r O {

CGaussJor::-CGaussJorO (

void CGaussJ0r::CalculaiCContexto 'ctxl {

void CGa~~~Jo~::OrdenaicContexto 'ctxl {

void CGaussJ0r::ResuelveIcContexto 'CtXl (

)

1

I )

double ECUaC [NUMI INUMtll ,Pivote [NUMI : int NUmECU=O; int i, j , k . iter; double piv.aux:

113

Page 136: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

//Obtiene datos de entrada N u m E c u = c t x - > M l - s G e t R e n ( ) ; for (i=O;icNumEcu;i++)

for ij=O;jclNumEcu+l) ;j++) Ecuac íil [jl =ctx->Ml->GetCelda ii. j 1 i

//Metodo de Gauss-Jordan for (k=O;kcNumEcu;k++){

if iEcuacIk1 [kl==Ol ( / / Metodo Auxiliar de intercambio de renglon iter=k; do{

iter++; if (iter>=NumEcu) [

//Caso de Error Ctx- >SetRes ( O i ; return;

for li=O;ic=NumEcu;i++)[ aux=Ecuac Lkl lil ; ECuaC [kl [i] =ECuaC liter1 [il ; Ecuacliterl [i] saux;

1 ) while (Ecuac ikl ikl = = O 1 ;

piv=Ecuac [kl [kl ; for (i=k;ic=NumEcu;i++)

for li=O;i<NUmECu;i++) { Ecuac [kl [il /=piv;

if (i!=kl { for (j=k;jc=NumEcu;j++)

for [j=k;jc=NumEcu;j++l Pivote Ijl =ECuaC [kl [jl *Ecuac iil lkl (-1) ;

Bcuac lil [jl +=Pivote ijl ; 1

1 1 //Guardar Resultado Ctx-SetRes (1) ; Ctx- 942 - SetRen (1 1 ; ctx->MZ->CetCOl INumEcu) ; f o r (i=O;icNumEcu;i++l(

auX=ECuaC [il INumEcul ; ctx->MZ- >SetCelda ( O , i, auxi ;

1 1

)

// Código del Archivo MediaArih

double CGauscJor::GetResultadoO { return o;

#if !definedlAFX-MEOIAARI) #define AFX-MEDIAARI #include "Strategy. h" class CMediaAri : public CStrategy { public:

void SetMedialdouble dato); double GetMedia 1 1 ; virtual void Calculaiccontexto *ctx); virtual void Ordenalccontexto 'ctxi; virtual void ResuelvelCContexto *ctx): virtual double GetResultadoO; CMediaAri I i ; virtual -CMediaAiriO;

CStrategy *obj; double media;

private :

114

Page 137: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Cas0 de Prueba 2

1; #endif

// Código del Archivo MediaAri.cpp #include "MediaAri. h" #include "Suma.h" CMediaAri: :CMediaAriO (

CMediaAri::-CMediaAXiO (

void CMediaAri::Calcula(CC&ntexto *ctx) (

1

double cumatoria=O; double aux=O; int N=O; obj=new CSumaO; obj ->Calcula (ctx) ; sumatoria=obj->GetResultado(); N=CtX-,L1- >GetN 1) ; if (N==O)

/ /caso de error aux=NULL;

aux=sumatoria/N; else

SetMedia laux) ; ctx->SetReslaux);

)

)

)

1

void CMediaAri::OrdenaíCContexto *ctx) (

void CMediaAri::Resuelve(CContexto *ctx) (

double CMediaAri;:GetResultadoO ( return media;

double CMediaAri: :GetMediaO ( return media;

void CMediaAri::SetMediaídouble dato) ( media=dato;

)

Código Refactorizado

//Parte del Código del Archivo Contexto.cpp ...

case * 5 * : //Ordenar Lista Opcionlll=MenuOrdenaCiono; switch (opcionlil) ( case '1,: //Metodo de la Burbuja

Str=new CBubbleO ; ~ t ~ - s A l g o r í t m o T n t ~ r f e z ( t h i s ) ; break;

str=new CShellO; S t T - s A l g o r i t m o I n t e r f a z ( t h i s ) ; break;

case * 3 ' : //Metodo de Selection s t r a w CselecO; ~ t ~ - s A l g 0 r i t m o 1 n t ~ r f a r O ; break;

case ' 4 , : //Metodo de Insercion str=new CInsercO ; 9tr-,Algo=itmoInterf~=(thi=); break;

case , 2 ' : //Metodo Shell

1

115

Page 138: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

break; 1

) while lopcionli!=io');

) while lopcioni!='o'); Ll=&Listal: ~Z=&ListaZ: L3=&Lista3; break;

case ' 2 ' : //Calculo de Medidas de Tendencia Central do(

~ p c i o n l = M e n ~ T e n d e n c i a C e n t r a l O ; switch lopcionl) [ cace ,l': //Media Aritmetica

Str=new CMediaAri 1 ) ; C t r - z A l g o ~ í t m o I n t e r f B . 0 ; result=GetRes(); if lresult==NULL)

else

getchil ; break;

Str=new CMediaArmO; str- z-AlgoritmoInterf az I this I ;

if lresult==NULL)

else

getch I I i break;

s t r a w CMediaGeoO; 9tT->AlgoritmoInterfae (this) ; reault=GetResO; if lresult==NULL)

else

getchi) i break;

Str=new CMediaCuaO; s t r - ~ A i g o r i t m o I n t e r f a . O ; reSult=GetResO; if iresult==NULL)

else

getchll i break;

Cts=new CMedianaO; 9 t ~ - ~ A l g O r i t m o I n t e r f a z O ; result=GetRes I ) ; if lresult==NULL)

else

getchil; break;

case '6': //Moda C t r = n e w CModaO; S t T - > A l g O I i t m O I n t e r f a z ( t h i s l : reCult=GetPararnetrall~ :

printf ("\nPrimero debe introducir elementos en la Lista'');

printf ("\nLa Media Aritmetica e s : Olf",resultl;

case ' 2 ' : //Media Armonica

result=Getnes(l;

printf I"\nPrimero debe introducir elementos en la Lista");

printf ("\nLa Media Armonica es: %lf",result);

case ' 3 ' : //Media Geometrica

printf ('\nPrimero debe introducir elementos en la Lista");

printf ("\nLa Media Geometrica e s : %if",resultI;

cace ' 4 ' : //Media Cuadratica

printf ('\nPrimero debe introducir elementos en la Lista");

printf ("\nLa Media Cuadratica e s : Plf",result) i

case '5': //Mediana

printf ("\nPrimero debe introducir elementos en la Lista");

printf ("\nLa Mediana es: %lf",resulti;

116

Page 139: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

if (result==o) { printf ( " \ n ~ o existe Moda, todos los datos son diferentes o

no hay datos"); I else(

if irecuit==i) ( recult=GetResO; printf ("\nLa Moda e s : %lf'*.result);

I else(

printf ("\nExisten %.Olf modas",result) ;

break; I

) while iopcionl ! = O ' I ; break;

// Código del Archivo Strategy.h #if !defined(AFX-STRATEGY) #define AFX-STRATEGY #include "Contexto.h" class CContexto; class cstrategy { public:

CStrategy i I ; virtual -cstrategyo";

/ / virtual void CalculaíCContexto *ctx)=O; // virtual void Ordena(CContext0 *ctxl=O; // virtual void ResuelveíCContexto *ctx)=O;

virtual double GetRe~ultadoO~O; virtual void AlgoritmoInterfaz ( CContexto etx I - O ;

1; tiendif

// Código del Archivo CAlgor1.h üifndef -CAlgorl #define -CAlgorl #include 'Strate9y.h" #include "Contsxt0.h" ciao* CAigori : public c~trategy ( public:

CAlgorl( I ; virtual -CAlgorl( );ir

virtual void Ordena ( CContexto ctx I - O ; void Algoritmolnterfaí ( CContexto f ctx I ;

1 ; #endif

// Código del Archivo CAlgorl.cpp

1 1

>

#include "CA1gorl.h' CAlgOr1::CAlgorlí 1 {

CAlgOrl: :-CAlqoTl~ 1 (

void CAlgor1::AlgOritm0Interfaz 1 ccontexto ctx ) ( Ordena(ctx1;

//Código del Archivo CAlgor2.h #ifndef -CAlgorZ I1

117

Page 140: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

#define -CAlgorZ #include mStrategy.h" #include "Context0.b" class CAlgorZ : public CStrategy ( public :

CAlgorZ( ) ; virtual -CAlgor2 ( I ; virtual void Reeuelve ( CContexto ctx I - O; void AlgoritmoInterfaz í CContexto * ctx ) ;

1; #endif

// Código del Archivo CAlgor2.cpp

1 1

1

#include 'CAlgor2.h" CAlgorZ: :CAlgorL( ) (

CAlgOr2 : : -CAlgorZ í ) (

void CAlgor2::AlgoritmoInterfaz ( CContexto CtX { Resuelve (ctx) ;

// Código del Archivo CAlgor3.h #ifndef -CAlgor3 #define -CAlgor3 #include .Strategy.h" #include "C0ntexto.h' class CAlgor3 : public CStrategy ( public:

CAlgor3( 1 ; virtual -CAigor3( ) ; virtual void Calcula ( CContexto Ctx ) E O; void AlgoritmoInterfaz ( CContexto CtX ) ;

1; Wendif

// Código del Archivo CAlgor3.cpp

1 1

1

// Código del Archivo Shel1.h

#include "CAlgor3.h" CAlgor3 : :CAlgor3 ( I (

CAlgor3: : -CAlgor3 ( I (

void CAlgor3::AlgOritmOInterfaZ ( CCOntextO * ftX ) ( Calcula(ctx1;

#if !defined(AFX-SHELL1 #define AFX-SHELL #include "CA1gorl.h" class CShell : public CAlgor1 ( public: / / virtual void Calcula(CC0ntexto 'ctx);

v ir tua l void ordenaiccontexto *ctx); // virtual void ResuelveíCContexto *ctx);

virtual double GetResultadoO; CShell(1 ; virtual -CShell(l ;

1; Uendif

// Código del Archivo Shell.cpp Uinclude "She1l.h"

118

Page 141: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

CShell: :CShellO { 1 Cshell: :-CshellO ( 1 //void C S h e l 1 : : C a l c u l a ~ c C o n t e x t o *ctxl ( / I 1 void CShel1::OrdenalCContexto *ctX) (

CElernento *AptNOdol.*AptNOdo2: double x ; int i,j,k,l,n,inter; n=ctx- >L1- zGe tN I ) : inter=n/z; while (inter>Ol (

for li=inter;icn;i++i( j=i-inter; while ( j > - l l (

k=j+inter; AptNodol=ctX->Ll->GetHO; ' A p t N O d o 2 = ~ t ~ - ~ L 1 - > G e t H O ; for il=l;l~=j;l++~

.for íl=l;l<=k;l++) ctx-711-sSiguientelAptNodoll;

ctx-~Li->Ciguiente(AptNodo2I ; if lIAptNodol-~ED-zGetEDo)c=lAptNodo2-~ED-~G~tEDl~~~

j=-1; else( x=AptNadol-7ED->GetEDO; AptNodol->ED->SetEDlAptN0d02->ED-zGetEDl)); AptN0do2->ED->SetEDix~;

) j=j-inter;

1 I inter=inter/i;

) I I f )

)

//void CShel1::ReSUelvelCCOntexto 'ctx) (

double CShell::GetRecultadoOt [ return o;

//Código del Archivo GaussJ0r.h #if !definedíAFX-GAUSSJOR) ,, #define AFX-GAUCSJOR #include "CAlgorZ. h" class CGaussJOr : public CAlgor2 ( public : / / virtual void Calcula(CContexto *ctxl; // virtual void OrdenalCContexto *ctx);

virtual void ResuelvelCContexto *ctx); virtual double GetResultadOO ; CGau~sJor I 1 : virtual -CGaussJorO;

1 ; #endif

// Código del Archivo GaussJor.cpp

1

1

/ / I

#include "GaussJor. h" CGaus~Jor: :CGauccJorll (

C G ~ U C S J ~ ~ : : - C G ~ ~ S S J O ~ I I [

//void CGau~gJ0r::CalculalCCantexto 'Ctx) (

119

Page 142: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

. . . . , . , , $ . Anexo E. Código del Caso de Prueba 2

//void c~au~~j~r::Ordena(CContexto *ctx) (

void c~aucsjor::Reeuelve(CContexto 'ctx) { I / )

double E C U ~ C [NUM] LNUMtll ,Pivote [NUMI i int NUmECU=O; int i,j,k,iter; double piv,aux; //Obtiene datos de entrada N u m E c u = c t x - s M i - , G e t R e n ( ) ; for (i=O;icNumEcu;i++l

f o r ( j =o ; j c (NumEcutl) ; ] + + I E C U ~ C [il Ijl =ctx-,Mi-sGetCelda(i,jl ;

//Metodo de Gauss-Jordan for (k=O;kcNumEcu;k++l(

if (Ecuaclkl ikl==O)( / / Metodo Auxiliar de intercambio de renglon iter=k; do í

iter++; if (iter>=NumEcul (

//Caso de Error ctx->SetRes I O ) ; return:

I for (i=O;ic=NumEcu;i++)(

aux=Ecuac [kl [il ; ECUaC Ikl iil =ECUaC iiterl íil ; Ecuac[iterl iil =aux;

I ) while (Ecuac [kl íkl = = O ) ;

) piv=Ecuacikl ikl ; for (i-k; ic =NUmECU; it t)

for (i=O;icNumEcu;i++l( ECUaC ikl iil /=piv;

if li!=kl ( for ( j =k; j c=NUmECU; j ++ 1

for I j =k; j <=NumEcU; j ++ I Pivote [jl =Ecuac lkl Ijl *ECUBC i i i Ikl 1-1) ;

Ecuac[il [jl+=Pivoteijl;

//Guardar Resultado ctx-sSetRes 11) ; Ctx->Mi->SetRen (1) ; CtX- >M2 - >SetCOl INumEcu) ; for (i=O;i<NumEcu;i++l {

aux-EcuacIil LNurnEcul : ctx->M2-,SetCeldaiO, i,auxi ;

1

1

double CGauSSJ0r::GetResultadoI) { return O ;

// Código del Archivo MediaAri.h #if !definedIAFX_MEDIAARI) itdefine AFX-MEDIAARI #include '"CAlgor3.h" class CMediaAri : public CAlgor3 ( public:

void SetMedia (double dato) i double GetMedia 0 ; virtual void CalculalCContexto * C t x ) :

/ / virtual void OrdenaíCContexto 'Ctx);

120

Page 143: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo E. Código del Caso de Prueba 2

/ / virtual void Recuelve(CContexto * c t x l ; virtual double GetRGsultadoO; CMediaAri 11 ; virtual -CMediaAri();

CStrategy 'obj : double media:

private :

) ; #endif

// Código del Archivo MediaAri.cpp #include "MediaAri. h" #include "Surna.h" CMediaAri: :CMediaAri ( I (

CMediaAii : : -CMediaAri 1 )

void CMediaAri::CalculalCContexto *CtXl (

1 1

(

double sumatoria.0; double aux=O; int N.O; obj=new CSumaO ; obj->Algori~moInterfaa(ctx); aumatoria=obj- ,GetResuitadoo;

if lN==Ol N=ctx->Ll->GetN ( ) ;

//caso de error aux=NULL;

aux=sumatoria/N; else

SetMedia laux) ; Ctx-SetReS lauxl ;

1

// 1 111

1

1

1

//void CMediaAri::OrdenalCCOntexto *CtX) (

//void CMediaAri::Resuelve(CContexto *ctxI (

double CMediaAri::GetResultadoO { return media:

double CMediaAri: :GetMedia() ( return media;

void CMediaAri::SetMedia(double dato) ( media=dato;

121

Page 144: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

Anexo F) CÓDIGO DEL CASO DE PRUEBA 3

Código Original

// Código del Archivo MarcoEstadCTX.cpp #define Pasox 20 #define P a s o Y 15 #include cctdlib.h> #include cconio.h> #include cdos.hz #include "MarcoEstadCTX.HPP'' #include "CysXY.H?P" / / #i #include <bios.h> #include 'lCTXBotOn. HPP" #define DeCOlor 1 / / void _ContxEj,,xY::_Interactuall

/ / {

ifllñotonl = new Boton~50,5o,üO,70,B1anco,Rojo,ll )==NULL1 ( closegraph I 1 ;

122

Page 145: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

printf ("ERROR 1: NO hay memoria en el Heap para salvar la Imagen."): printf 1''presione enter para terminar ,'I i getch i ; exit (1) ;

) ifllaApt = new P a l ~ t ~ ( 8 . 2 . U p C . ü e C ~ 1 0 r . P a l C 0 1 a r e s l !==NULL1 //Paleta de Colores.

( printf I"ERROR 1: NO hay memoria para salvar l a canva de la paleta"); printf ("Presione enter para terminar ; getchi); closegraph i 1 ; exit (1) ;

1; Mo~se.ViSUalON0; Mouse.GetCaord(&Mx. &My) i do [ Mouse.GetCoordI&Mx, &My);

if lMouse.Pulsa-LO) [ MoUSe.GetCOOrdl&MX, &My); Mouse.VisualOFF0; iflaApt->Cursor-INlMx, My))

if IBotonZ ! = NULL) ; [ 0otonZ r aApt->GetBotonlMx, Myl;

B0tonl-~SetCol~F~Boton2-~~GetEü~l-z~GetaAptO-~GetColorO~; Botonl->Show();

(

) ] / / termina if

//delayílOol i MoUSe.ViSUalON0;

else if (bioskey(l1)

) while lTECLA!=ECC) ; TECLA = bioskey(0) ;

/ /

ifllaApt = new -SysxYl O , o, 576, 180. MaxX, MaxY, MaXX, MaxY, O , O , 576, 180, Pasox, PasoY))==NULL)

( closegraphl); printf ("ERROR 1: No hay memoria en el ueap para salvar la Imagen."); printf ('Presione enter para terminar " 1 ; getch0 i exit (1) ;

I delay(500) ; whilel!kbhitO) / / Refresca el segmento

' ( aApt->HideO; delayi500) i aApt - >Show í ) ; delay i 500 1 i

) / / whilel!kbhitO).

/ / termina interactua / / Total LOC 118.

// Código del Archivo Figura.hpp / / Fecha de Actualización: Agosto 22 del 2003 / / üefinici6n de la clase Figura. / / El archivo se nombra *'Figura.HPP'Y #ifndef La-Figura #define La-Figura #include <stdio.h> #include "Tipos .HPP" #include "Elem4A. HPP" //#include "ED. HPP" class -ED; class -Figura

( public:

123

Page 146: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

- Figura ( j ; virtual --Figura0 ; virtual void ShowO=O; virtual void HideO=O; virtual void PushO=O; virtual char *GetTxO=O; virtual unsigned int GetColor()=O; virtual void SetColrFlColor Colr)=O;

/ / templatecclacs Ts // virtual -Elernentoc-ED * > *GetBotoniunsigned, unsigned) = O ;

virtual Boolean Cursor-INlunsigned int Xp. unsigned int Yp) =O; } ; / / Termina la clase -Figura.

Uendif

// Código del Archivo Boton.hpp / / Módulo de definición de la clase Botón / / El archivo se llama Boton.HPP. / / Fecha de actualización: ll/Mayo/1993 üifndef Un-Boton #define Un-Boton #include <graphics.h> #include cstring.h> U include '"Figura. HPP" #include 'Tipos.HPP" class Boton: public -Figura

( protected: unsigned X1, Y1, X2, Y2; Color COlorM, ColorF, ColorTxt; unsigned Ashurado; char 'Texto; unsigned XTx, YTx; Boolean Activo;

public: Botonlunsigned int Xm , unsigned int Ym , unsigned int XM , unsigned int YM ,

Color COlM , Color ColP , Color ColTXt , unsigned int Ash , char *TxJ (xi = xm; ~i E Ym; X2 = XM; Y2 = YM; ColorM = ColM; ColorF = CO1F; Ashurado = Ash; COlorTxt ji COlTXt; UnsiQned LOnQT - strleniTxi: / / LonQitud de la cadena en unidades de texto - - . . . - if (LongT+8 >= x2-x1-6)

{ LongT = lX2-X1-6)/8; / / Calcula la lonqtud del titulo en unidades de texto ~ .

/ / 8 representa el tamamo en pixeles de un caracter. / / La división entre 8 e s para convertir número de pixeles a unidades de texto. / / Aquí se termina el ajuste del titulo.

Texto - new char[LongTl; / / Reserva memoria para el tftulo. strcpy(Text0, ""I ; strncat(Texto,Tx,LongTj; / / Función de C++ que hace un 'append'

/ / de LOngT Caracteres de la cadena TX Con la cadena Texto. XTX = Xi+S; YTx = Yl+(YZ-YlJ/2-2; / / YTx = Ylt(YZ-Y1-8)/2;

I else

( Texto = new charILongT1; / / Reserva memoria para el título. if (TX = = NULL)

else

XTX = Xi+2+(X2-Xi-LongT*81/2; YTx = Yl+IYZ-Y11/2-2; / / YTx i Yl+IY2-Y1-81/2;

ctrcpy(Text0,");

StrCpylTeXtO,Txl;

} ; / / Termina el if. S h o w O ;

) / / Constructor de la clase Boton. virtual -BotonO ;

124

Page 147: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

void Crea( unsigned int x11, unsigned int Y11,

Boolean Cursor-IN(unsigned int Xp, unsigned int Yp); void ShowO; void Pinta 1 ) ; void Hidel) ; void Push 1 ) ; float GetX10 ; float GetX2 11 ; float GetYlO; float GetY20; char 'GetTxO ; unsigned int GetColorO; unsigned int GetAchuradoO; Boolean GetEdoO;

void Setxi(unsigned int VarXI ; void SetXiIunsigned int VarX); void CetYl(unsigned int vary); void SetY2Iunsigned int Vary) ; void CetTxlchar +TX) ; void SetColrM(Col0r Col=) ; void SetColrF(Col0r Colr) ; void SetCOlrTX(COlor Colr); void SetEdolBoolean Edo) ;

unsigned int colorl. unsigned int Color2, char 'T ) :

/ / Elementoc-ED * > 'GetBotonIunsigned P x , unsigned Py);

) ; / / Boton. #endif

// Código del Archivo Boton.cpp / / Módulo de implementación de funciones miembro de la clase "Boton". / / El archivo se llama "Boton.CPP' / / Fecha de actualización: 2e/marzo/1994 #include cdos.h> #include "Boton .HPP" Boton: :-BotonO

( delete(Text0); Texto = NULL;

) / / Destructor de la clase Boton.

{ i f (1x1 <= xp && xp c = x2) && Boolean Boton::Cursor_INiunsigned int Xp, unsigned int Yp)

(Y1 <F Yp hh Yp < = Y2)) { if(Activo1

Push ( 1 ; return (TRUE1 ;

else return(FALSE1 ; )

) / / Cursor-IN. void Boton::Crea(unsigned int Xll, unsigned int Y11, unsigned int Coloil, unsigned int COlorZ, char *TI

( /*Xl = x11; Y1 i yI.1; X2 = Xl+strlenlT)*ü+ü;

strCpy(Etiq.T) ; y2 = yi+ia;

color-I F colorl; Color-T F COlor2;*/

1 / I Crea.

( unsigned Oldcolor = getcolor0; void B0ton::ShowO

setcolor ICOlOrMI ; rectangle 1x1. Yl.X2, Y21 : setfillstylelAshuiado, Colorfli / / Pone relleno en color del Fondo. ba~(Xl+l,Yl+l.X2-1,Y2-1);

setcolor(Col0rTxt); / / función de Ctr que establece el color. moveto IXTx , YTx) ; outtextliexto);

/ / Aquí se coloca el título del Botón . . . . .

125

Page 148: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

SetcoiorIElancoEl: lineiX1+2.~l+i.x2-l,Yl+l); l i n e l X l + z . ~ 1 + 2 , x 2 - 2 , Y 1 + 2 ) : linelx1+2,~l+l.x1+2.Y2-1); line(Xl+3,Yl+Z,Xl+3,Y2-2); setcolor (Gris) ; line (X2-1, Yltl, X2 -1, Y2 -1 i ; linelX2-2,Y1+2.XZ-Z,YZ-2) ; linelX2-1.Y2-1,Xl+2,Y2-l); line 1x2-1, Y2-2. X1+3, Y2-2) ; Activo = TRUE; setcolor IOldColor) ;

) / / Show.

( unsigned OldColor = getcolorl); void Bot0n::PintaO

setcolorlColorM); rectangle 1x1 ,Y1, xz. Y21 ; Setfillstyle(Ashurado, ColorF); / / Pone relleno en color del Fondo barlX1+1,Y1+1,X2-1,Y2-l);

setcoior(ColorTxt); / / Función de C++ que establece el color. rnovetolXTx.YTx) ; out t ext (Texto) ; Activo = TRUE; setcolorl0ldColor);

/ / Aquí se coloca el titulo del Botón . . . . .

) / / Pinta.

I setcolor icoior~) : void B0ton::HideO

rectangle (xl.Yl,Xz ,Y2) ; setfiilstyle(CL0SE DOT-FILL. Gris); / / pone relleno compacto en color gris. bar (X1+1 .Yl+l,X2-1;YZ-i) ; Activo = FALSE;

void Bot0n::PuahO ) / / Hide.

( unsigned OldColor = getcolor0; 8etfillstylefAshurado. ColorF); / / Pone relleno en color del Fondo. bar(Xi+l.Yl+l,X2-l,Y2-l) ; / / Aquí se coloca el titulo del B o t h . . . . . setcolor(Co1orTxt); / / Función de C++ que establece el color. rnovetolXTx,YTxl ; outtextiText0); delayIlO0) ; Betcolor IBlancoE) ; lineiX1+2,Y1+1,X2-l,Yl+l) ; linelXl+2,Y1+2,X2-2,Yi+2); linelX1+2.Yl+l,X1+2.Y2-1~; line íX1+3. Y1+2,Xl+3 .Y241 ; SetColorlGric) ; line 1x2-1, Yl+l, X2-1, Y2-1) ; linelX2-2,Yl+2,X2-2.Y2-2); lineiX2-l.Y2-1,X1+2,~2-li; linelX2-1,Y2-2.Xl+3.YZ-Z); setcolor (Oldcolor) ;

) / / Push, float Boton::GetXlO

f returnlxll: . . . , ~-~ ] / / GetX1.

float Boton: :GetX2 11 [ returnlx2) ; ) / / GetX2.

( returniyi); ) / / GetY1.

( return (y2 ) ; ) / / GetY2.

float Boton: :GetYlO

float Bot0n::GetYZO

char 'Boton: :GetTxO

126

Page 149: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

( returniTexto1; ] / / GetTx.

( if(CurSOr-INiPX, Pyll; /*-Elementoc-ED * > 'Boton::GetBoton(unsigned Px. unsigned Pyl

( / / Aquí va el texto para regresar un apuntador al elemento 1

] * / / / GetBoton. unsigned int Boton::GetColorO

( returnICOlorF1; ) / / Getcolor.

( return(Achurado1 ; 1 / / GetAshurado.

Boolean Bot0n::GetEdoO ( returnIActivo1 ; ) / / GetEdo.

unsigned int B0ton::GetAshuradoO

void B0ton::SetXlIunaigned int VarXl ( x1 = varx; ) / / setx1.

( x2 = varx; ) / / setx2.

( Y1 i vary; ) / / Cetyl.

( Y2 = vary; ) / / SetY2.

void Boton::SetXZIunsigned int varxl

void Boton::SetYlIunsigned int VarYl

void Boton::SetYZ(unsigned int Vary1

void BOton::SetTx(Char *Txl ( unsigned LOngT = strlenlTx); / / Longitud de la cadena en unidades de texto.

if lLOngT*8 >= X2-Xi-61 ( LongT = lx2-x1-6l/a; / / Calcula la longtud del título en unidades de texto

/ / 8 representa el tamaño en pixeles de un caracter. / / La división entre 8 es para convertir número de pixeles a unidades de texto. / / Aquí se termina el ajuste del titulo.

Texto = new charlLongT1; / / Reserva memoria para el título. strcpy(Text0, " " I i strncat(Texto.Tx.LongT1; / / Funci6n de C++ que hace un 'append'

XTX I Xlt5; YTX = Ylt(YZ-Y11/2-2; / / YTx = Ylt(Y2-Y1-81/2;

/ / de LongT caracteres de la cadena TX con la cadena Texto.

I else

( Texto = new char[LongTI; / / Reserva memoria para el titulo. strcpylText0,Tx) ; XTx = xi+2+lx2-xl-LongT*81/2; YTX = Y ~ + ( Y ~ - Y ~ I / z - ~ ; / / YTX = Y ~ + I Y z - Y ~ - ~ I / z ;

1; / / termina el if. ) I / SetTx.

( ColorM = Colr; ) / / SetColrM.

void Boton::SetColrM(COlor colrl

void BOton::SetCo1~FlCO10r Colrl ( COlOIf = coir; 1 / / SetColrF.

( COlorTXt = Colr; ) / / SetColrTx.

( Activo = Edo; ) / / SetEdo.

void Boton::SetColrTxiColor Colrl

void Boton::SetEdo(Boalean Ed01

// Código del Archivo Circulo.hpp Uifndef Un-Circulo #define Un-Circulo #include cconia.h>

127

Page 150: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

#include cctdlib.h> #include "Tipos .HPP" #include "Punto. HPP" #include "Figura.HPP*' class Circulo: public -Figura { / / private:

protected: Thick ThickL; TipoL StyleL; unsigned Colorc; float Radio; Punto P1; Boolean Visible;

Circulolfloat wxi, float Wyl. float wx2, float Wy2. public:

float Vxl, float vyl. float VxZ. float VyZ. float x1, float yl, float r , Thick ThL , TipoL TL , Color C ) ;

virtual -Circulo I) ; void Show0 ; void Hide0 i void Redraw(f1oat Wxl, float Wyl, float Wx2, float WyZ,

float GetXO; float GetYO; void SetXlfloat Varx); void SetYlfloat Vary); float GetRadio 1) ; void SetRadiotfloat R ) ;

float vxl, float vyl. float Vx2. float Vy2);

); / / circulo. #endif

// Código del Archivo Circulo.cpp #include "Circulo.HPP's Circu1o::Circulolfloat Wxi. float Wyi, float Wx2. float wy2,

float Vxl, float Vyl. float Vx2. float Vy2. float x1, float yl, float r, Thick ThL, TipOL TL, Color C)

( ThickL = ThL; StyleL = TL; co1orc = c; Radio = r; Visible = FALSE;

8etlineStyleIStyleL.1,ThickL); static Punto *P = NULL; ifllP = new Punto1 )]==NULL)

closegraph 1) ; printf ("ERROR 1: No hay memoria en el Heap para salvar la Imagen."); printf ("Presione enter para terminar " ) ; getchl); exit (1) ;

(

P1 F *P; Chow 1 ) ;

)

delete IP) ;

Circulo: :-Circulo 1 ) ) / / Constructor de la clase circulo.

{ / / . . . ) / / Destructor de la clase Circulo.

( if (!Visible) void Circulo: :Show0

(SetcolorlColorC); circle lP1 .Tp [ O 1 , P1 .Tp Ill, Radio) ;

Visible = TRUE: ) / / Si no esta Visible.

) / / Show. (Dibuja el circulo en la pantalla)

( if (visible) void Circulo: :Hide0

128

Page 151: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

(setcolorlcolorc - Colore); / I cetcolorlColorCl circlelP1.Tp [o1 , Pl.Tp(l1, Radio1 ; Visible = FALSE;

] / I Si esta Visible. ] I / Hide. (desaparece el circulo de la pantalla).

void Circu1o::Redrawlfloat Wxl, float wyl. float wx2, float Wy2. float vx1, float vy1. float VXZ, float VY2)

( Hidell; ~ ~ t l i n ~ 5 t y l ~ I S t y l e L . 1 , T h i c k L ) : Punto P O : P1 = P: ShowO;

) I / Redraw. Reconstruye la gr fica. float Circulo: :GetxO

{ return IPl .Tp [O1 I ; 1 I / Getx.

float Circu1o::GetRadioll { return1Radio); ) / / GetRadio.

f1oi.t Circulo: :GetY() { returnlP1.Tpíllj; ) / / GetY.

( Radio = R; 1 / / GetY2.

{ Pl.Tp[Ol = VarX;

void CirCulo::SetRadio(float Rl

void Circu1o:;SetXlfloat VarXi

) I1 setx.

1 I / CetY.

void Circu1o::SetYlfloat vary) { Pl.Tp[lI = Vary;

// Código del Archivo Paieta.hpp / I Módulo de definición de la clase "Paleta" I / El archivo se llama "Paleta.HPP" / / Fecha de actualización: 17/marzo/1994 #ifndef Una-Paleta #define Una-Paleta #include cgraphics.h> #include 'Tipos.HPP'' #include "FigUra.HPP" #include "ListaG.HPP" enuim PosPal { Lfup = o. upc = I, Rhup = 2 , / / o 1 2 / /

LfC = 3 , C = 8 , RhC = 4 , / / 3 8 4 / / LfLo = 5 , LoC = 6, RhLO = 7 , / / 5 6 7 I / cousr= 9); / / Definido por el usuario.

class Paleta: public -Figura { private:

- LiStaG 'L; - Figura 'Objl; unsigned X1, Y1. x2. Y2; / / Coordendas de la paleta de ~ e n ú s . unsigned NV; / / Número de opciones Verticales. unsigned NH; I / Número de opciones horizontales. PoSPal PosPaleta: Color COlOiOpC. ColoZFondo; char *Texto; void SetCoordenadaslunsigned int XL, unsigned int YT. unsigned int XR, unsigned int

YE. unsigned int LngV, unsigned int LngHl; / I Establece las coordenadas de la paleta. public:

* / / * .__.. Paleta de Colores ...-.

virtual -Paleta(); Paletalunsigned int OpV, unsigned int OpH. unsigned int P o s . int x, char *Pall;

Boolean CUTSOT-INI unsigned int Xp. / / Verifica si el cursor está

float GetX10; float GetX2lI;

unsigned int Ypl; / I dentro de la paleta.

129

Page 152: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

float GetY10; float GetY20; ckzr 'GetTxO; char 'GetTxIunsigned int Px, unsigned int Pyl : unsigned int GetColor(uncigned int Px. unsigned int Pyl;

void SetX1 (unsigned int VarX) i void SetX2(uncigned int VarXl; void SetYl (unsigned int Vary) ; void SetY2 (unsigned int Vary) ; void ShowO; / / Refresca la paleta. void Hide 1 1 ; / / oculta l a paleta. void CetBotones(); / / Establece las hotones de la paleta void PushO; unsigned int GetColorO; "old SetCOlrFlColor Coiri();

/ / - Elemento<-ED 'GetBotonIunsigned Px, unsigned Py);

) ; / / Pzieta. #endif

// Código del Archivo EjeY.hpp #ifndef un-EjeY #define un-Eje: #include ''LiStaG.HPP" #include ''Linea.HPP" #include ''Figura.HPP'7 class -EjeY: public -Figura

( protected: - Figura *Obj l ; - LictaG *L;

public: - EjeYO; - EjeYI float Wxl, float Wyl. float Wx2, float wy2, float Vx1. float Vyl,

float Vx2, float vy2, float x1. float yl, float x 2 , float y2, unsigned int Intervalos, Color C , TipoL TL , Thick ThLl;

virtual --EjeYll; void Show(1 ; void Hide0 ; void Redraw( I ;

void PushO(); char 'GetTxO ( I : unsigned int Getcolor I 1 [ ] ; void SetColrFIColor C o l r l [ ) ;

Boolean Cursor-INlunsigned int Xp, unsigned int Yp>(); / / - Elemento<-ED *> *GetBOtOn(unCigned, unsigned)[);

) ; / / -EieX. #endif

// Código del Archivo EjeY.cpp #include cconio.h> #include cstdlib.h> #include "GPunto.HPP" #include ,,EjeY.HPP" - E j eY : :-E j eY 1)

1 ; - EjeY::-EjeYl float Wxl, float wyl. float wx2, float wy2, float Vxl, float Vyl.

float Vx2. float vy2. float x1, float yl, float x2, float y2. unsigned int Intervalos, Color C . TipoL TL. Thick ThL)

( L = new -ListaGll; / / L = NULL: ifllOhjl = new Lineal wx1, wyl, wx2, wy2, vx1. vyl, Vx2, vy2.

X1, yl. X1, y2. C. TL, ThLll=sNULLl ( Ilclocegraphil i printf 1"ERROR 1.: NO hay memoria en el ~ e a p para salvar la Imagen."l i printf ("Presione enter para terminar ''I ; qetchli;

130

Page 153: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo F. Código del Caso de Prueba 3

closegraphl) ; exit 11) ;

I - ED 'Ptr; Ptr = new -EO();

L-)-Agrega(Pt); I / - Elemento<-ED * > 'Pt = new -Elementoc-ED *>lPtr, NULL, NULL);

unsigned Delta = abs(ly2-yl)/Intervalo~); forlint i=l; i<=Intervaloc; it+)

(ifllobjl = new GPuntol wx1. WYl. wx2, wy2, Vxl. Vyl, VxZ. Vy2. x1, yl, C))==NULL)

i //closegraphO; printf ["ERROR 1: NO hay memoria en el Heap para salvar la Imagen."); printf ("Presione enter para terminar ' I ) ;

getch 1 ) ; closegraph 1 ) ; exitll);

Ptr = new -ED();

L-sAgrega1Pt) ;

)

/ / Pt = new -Elementoc-ED *>lPtr, NULL, NULL);

) / / Visible = TRUE;

) / / Constructor de la clase -EjeX.

{ delete(L); ) / / Destructor de la clase -EjeX.

void -EjeY: :show0 { /*if (!Visible)

- EjeY: : --EjeY I )

( L->-Visual-ONl);

) / / Si NO está Visible. Visible = TRUE;

*/ L->-Visual-ONO;

) / / Show. (Dibuja el -Elex en la pantalla].

{ /*if (Visible) void -EjeY: :Hide()

( L->-ViCual-OFF();

) / / Si está Visible. Visible = FALSE;

* / L->-ViaUal-OFF 1 ) ;

) / / Hlde.

( HideO;

(desaparece la línea de la pantalla). void -EjeY: :Redrawl)

Shawl); / / Redraw. Reconstruye una línea.

131

Page 154: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

Anexo C ) CÓDIGO DEL CASO DE PRUEBA 4

Código Original

// Código del Archivo Material.hpp #include cvcl.h> !+include cString.h> #include cGl\glu.h> #include <Gl\glaux.h> #include <vector.h>

class Material ( private:

string name; / / Vector cGLfloat, ambientcolor; / / vector CGLfloat, diffusecolor: I / vector cGLfloat> especularcolor; // Vector cGLfloat> emissivecolor;

GLEloat shininess; GLfloat transparency; GLint id; String pathTexturei

public:

132

Page 155: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. C6digo del Caso de Prueba 4

virtual void Setpoints(GLf1oat valuel, GLfloat valuei, GLfloat value3. GLfloat value4 .

virtual Avertex f Getpointsiint indiceJ=O; virtual void Setradius(GLf1oat valuel, GLfloat valuei. GLfloat value3, GLfloat value4,

virtual void Setlineas(GLf1oat valuei. GLfloat valuei. GLfloat value3, GLfloat value4.

virtual Line Getlineaslint indicel=O; void SetnamefString value); String Getnameil; void SetambientCOlorlGLfloat valuei. GLfloat valuei, GLfloat value3,GLfloat value4):

GLfloat values. GLfloat value61=0;

GLflOat ValUe5. GLfloat value6)=0;

GLfloat values, GLfloat valueóI=O;

~~~~

GLfloat GetambientColoriGLint value); void SetdiffUSeColoiiGLfloat valuel, GLfloat valuez. GLfloat value3,GLfloat value4l; GLfloat GetdiffUSeCOlorfGLint value); void SetespecuiarColoriGLfloat valuel, GLfloat valuei. GLfloat value3,GLfloat value4l; GLfloat GetespecularColoriGLint value); void S e t e m i s s i v e C o l o r ( G L € i o a t valuei, GLfloat value2, GLfloat value3,GLfloat value41; GLfloat GeternissiveColoriGLint value); void SetshininessiGLfloat valuell; GLfloat GetshininessO; void SettransparencyiGLfloat valuell; GLfloat Gettransparencyll; Material [ I ; -Material(); void SetidfGLint value); GLint Getidi! ; void SetpathTextUreIString value); String GetpathTextureO ;

);

// Código del Archivo ATorus.hpp #include <String.h> #if !defined (Material) # include "Material. hpp" #define Material #include "Material.hpp' #endif #if !defined(-Transform) U include "Transform.hppll #define Transform #include "Transform.hpp' Uendif class ATOTUS: public Material, public Transform { private:

String name; GLint id; GLint index; GLfloat interiorRadius; GLfloat exteriorRadius;

void SetnamefString value); String Getname0 ; void SetidlGLint value); GLint GetidO; void SetindexiGLint value); GLint GetindexO; ATOTUS 1 J ; -ATOTUS ( I ; void SetradiusiGLfloat valuel, GLfloat value2, GLfloat value3, GLfloat value4, GLfloat

GLfloat Getradius0 ; void S ~ t ~ x t ~ ~ i o ~ R ~ d i u S i G L f l o a t v a l u e ) ; GLfloat GetexteriorRadiusll; ATOTUClGLflOat valuel, GLfloat valuez); void SetpointsíGLfloat valuei, GLfloat value2, GLfloat value3, GLfloat value4. GLfloat

Avertex * Getpointslint indice)( return NULL;)

public :

Values, GLfloat value6l;

values. GLflDat value6l( )

133

Page 156: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

. . Anexo G. Código del Caso de Prueba 4

void SetlineasiGLfloat valuel, GLfloat value2, GLfloat value3, GLfloat value4, GLfloat

Line Getlineasiint indice)( return NULL;) values, GLfloat value6)( )

) ;

// Código del Archivo ABaseCyl.hpp #include cvcl.h> #include cString.h> #if !defined(-Materiall U include "Material. hpp" #define -Material #include "Material.hpp" #endif #if !defined(-Trancform) U include 'Transform.hpp" #define -Transform #include "Transform.hpp" #endif class AEIaseCyl: public Material, public Transform ( private: GLfloat radius; GLfloat height; String name; GLint id; GLint index;

void SetnameIString value); String GetnameO; void Setid(GLint value); GLint Getid(); void SetindexíGLint value); GLint Getindexil; void Setradius(GLf1oat valuel, GLfloat value2, GLfloat value3, GLfloat value4, GLfloat

values, GLfloat value6) ; GLfloat GetradiusO; void Setheight(GLf1oat value); GLfloat Getheight O ; AñaseCyl(1 ; -Añasecyl() ; AñaseCyl(GLfl0at valuel, GLfloat value2); void SetpointsiGLfloat valuel, GLfloat value2, GLfloat value3, GLfloat value4, GLfloat

AVertex f Getpoints(int indice)( return NULL;) void Setlineas(GLf1oat valuel. GLfloat valuei, GLfloat value3. GLfloat value4, GLfloat

Line Getlineas(int indice]( return NULL;)

public:

values, GLfloat value6)( )

value5, GLfloat value61( I

) ;

// Código del Archivo APolyhedron.hpp #include sString.h> #if !defined(-Material) 8 include "Material. hpp" #define -Material #include -Material.hpp" #endif #if !defined(-Trancform) U include "Transform.hpp,' #define -Transform #include "Transform.hpp' #endif class APolyhedron: public Material, public Transform { private:

String name; GLint id; GLint index; GLfloat radius:

public: void Setname(strin9 valuel i String GetnameO;

134

Page 157: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

void SetidlGLint v a l u e ] : GLint Getidll i void SetindexIGLint value); GLint Getindex0 ; APolyhedron 11 ; -~~olyhedronII; void SetradiuslGLfloat v a l u e l , GLfloat valuei, GLfloat value3, GLfloat value4, GLfloat

value5, GLfloat value61; GLfloat Getradiusll; APolyhedronlGLfloat value); void SetpointcIGLfloat valuei, GLfloat valuez , GLfloat value3, GLfloat value4, GLfloat

Avertex f Getpointslint indice)( return NULL;) void SetlineaslGLfloat v a l u e i , GLfloat value2. GLfloat value3, GLfloat value4. GLfloat

Line Getlineaslint indice) { return NULL;)

value5. GLfloat value61( )

values. GLfloat value6)( )

1 ;

//Código del Archivo Points.hpp #include cvcl.h> #include <String.h> #include cGl\glu.h> #include cGl\glaux.h> #include cvector.h> #if Idefinedl-Material) # include "Material. hpp" #define -Material #include 'Material.hpp" #endif #if !defined(Transform) U include 'Trancform.hpp' #define -Transform #include '"Transform.hpp" Uendif #if !defined(-Avertexl # include "Avertex. hpp" #define Avertex #include *AVertex.hpp' #endif class Points : public Material, public Transform ( private:

String name; GLint id; GLint index; Avertex *="xi;

// vector cAVertex, puntos; public:

int indp; Points11 i -Points0 ; void Setnamelstring value); String Getnamell; void SetidlGLint value) ; GLint Getidll; void SetindexiGLint value); GLint Getindexll; void SetpointsiGLfloat valuei. GLfloat valuei, GLfloat value3, GLfloat value4, GLfloat

value5, GLfloat value61; Avertex * Getpointslint indice); GLint GetSizevector(): void SetradiuslGLfloat valuei, GLfloat valuei. GLfloat value3. GLfloat value4, GLfloat

value5, GLfloat value6)( ) void SetlineaslGLfloat valuel. GLfloat value2, GLfloat value3, GLfloat value4, GLfloat

Line Getlineaslint indice)( return NULL;) value5. GLfloat Value6)( )

1 ;

:t

135

Page 158: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Casa de Prueba 4

// Código del Archivo Line.hpp #include cvcl.h> #include sString.h> #include <~l\glu.h> #include cGl\glaux.hs #if !defined(-Material1 U include "Material. hpp" #define -Material #include "Materia1,hpp" Uendif #if !definedI-Transforml U include "Transform.hpp" #define -Transform #include 'TranCform.hpp" Uendif #if !defined(-AVertexl U include "AVertex.hpp" #define -Avertex #include "AVertex.hpp'' #endif class Line : public Material, public Transform ( private: Avertex pointl; Avertex pointz; string name; GLint id; GLint index;

void SetnamelString value); string Getnamell; virtual -Line I 1 ; LinelGLfloat valuel, GLfloat valuez, GLfloat value3, GLfloat value4, GLfloat values.

public:

GLfloat value61: . . Line I I ; void SetidlGLint value); GLint GetidO i void SetindexIGLint value); GLint Getindex0 ; void Setpoints(GLf1oat valuei, GLfloat valuez, GLfloat vaiue3, GLfloat value4, GLfloat

value5, GLfloat value6); Avertex * Getpointsll; void SetpointZiGLfloat valuel, GLfloat valuez, GLfloat value31; Avertex * Getpoint2 I 1 ; void SetradiusiGLfloat valuei. GLfloat valuez, GLfloat value3, GLfloat value4, GLfloat

values. GLfloat value61 ( ) void SetlineasiGLfloat valuei, GLfloat valuez, GLfloat vaiue3, GLfloat value4, GLfloat

value5, GLfloat valueGI( ) Line Getlineaslint indice)( return NULL;]

i ;

// Código del Archivo Triangle.hpp #include cvcl.h> #include cString.hs #include <Gl\glu.h> #include <Gl\glaux.h> U if !defined (-Line1 U include "Line. hpp" #define -Line #include "Line.hpp" #endif #if !defined(-Material1 # include "Material. hpp" #define -Material #include "Materrai.hpp" Uendif #if !defined(-Transform1 U include 'Transform.hpp" #define -Transform #include 'Transf0rm.hpp" Uendif class Triangle : public Material, public Transform ( private;

136

Page 159: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

Line lineal; Line linea2; Line linea3; String name; GLint id; GLint index;

void setname(String valuel; String Getnameil; Triangle ( 1 ; -Triangle i I i void SetidIGLint valuel ; GLint GetidO; void SetindexIGLint valuel; GLint Getindexo; void SetlineaslGLfloat valuel, GLfloat valuei, GLfloat value3, GLfloaf vaiue4. GLfloat

Line Getlineaslint indice); void Setlineai(GLf1oat valuel, GLfloat value2, GLfloat value3, GLfloac value4. GLfloat

Line f GetlineaZO; void Setlinea3(GLfloat valuel. GLfloat value2, GLfloat value3, GLfloat value4, GLfloat

values, GLfloat value6i; Line * Getlinea30; void SetpointsIGLfloat valuel. GLfloat value2, GLfloat value3. GLfloat value4. GLfloat

Avertex Getpoints(int indice){ return NULL;) void Setradius(GLf1oat valuel, GLfloat value2, GLfloat value3, GLfloat value4, GLfloat

public:

value5, GLfloat value61;

value5. GLflOat value61;

values, GLfloat value61 ( )

value5, GLfloat value61( ) 1;

// Código del Archivo CPolygon.hpp #include <vcl.h> #include <String.h> #include <Gl\glu.h> #include cGl\glaux.hs #if idefinedí-Material1 # include "Materia1,hpp" #define Material #include "Materia1.hpp" #endif #if !defined(-Transform1 ü include "Transform. hpp" #define -Transform #include 'Transform.hpp', #endif #if !defined (-Line) # include "Line. bpp" #define -Line #include "Line.hpp" #endif class CPolygon : public Material, public Transform ( private:

Line lineas 1501 ; String name; GLint id; GLint index;

void Setname(Ctrin9 value); String Getname(); CPOlygO" I I ; -CPolygonO : void SetidtGL.int value) ; GLint GetidO; void SetindexlGLint value); GLint GetindexO; void SetlineasiGLfloat valuel, GLfloat value2, GLfloat value3. GLfloat value4, GLfloat

Line Getlineas(int indice);

public:

value5, GLfloat value61;

81

137

Page 160: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

void SetpointsiGLfloat valuel. GLfloat value2. GLfloat value3. GLfloat value4. GLfloat

AVertex f Getpointsiint indice)( return NULL;) void Setradius(GLfl0at valuel. GLfloat value2, GLfloat value3, GLfloat value4, GLfloat

values, GLfloat value61 ( )

values. GLfloat value6l( ) 1;

Código Refactorizado

// Código del Archivo Material.hpp #include <vcl.h> #include cString.h> #include <Gl\glu.hs #include cGl\glaux.h> #include <vector.hs class Material ( private: String name;

/ / vector cGLfloat, ambientColor; / / vector cGLfloat, diffusecolor: I l vector cGLfloat, especularColor; / / vectox cGLfloat> emicsivecolor; GLfloat shininess; GLfloat transparency; GLint id: String pathTexture;

public: / / virtual void Setpoints(GLf1oat valuel, GLfloat value2. GLfloat value3, GLfloat value4, GLfloat value5, GLfloat value61=0;

/ / virtual void CetradiusiGLfloat valuel, GLfloat value2, GLfloat value3, GLfloat value4, GLfloat values, GLfloat value6) = O ; // virtual void Setlineas(GLf1oat valuel, GLfloat value2, GLfloat value3. GLfloat value4, GLfloat values, GLfloat valueGI=ü; virtual Line Getlineas(int indicel=ü; void Setname(Ctring value); String Getnameil; void SetambientColoriGLfloat valuel, GLfloat value2, GLfloat value3,GLfloat Value4); GLfloat GetambientColor(GLint value); void CetdiffueeCOlorlGLfloat vaiuei. GLfloat vaiuez. GLfloat value3,GLfloat value4);

virtual Avertex * Getpointsiint indiceI=O;

~~~ ~. ~ ~ ~~~

GLfloat GetdiffuSeColor(GLint value); void SetespecularColoriGLfloat valuel, GLfloat value2. GLfloat value3,GLfloat value4); GLfloat GetespecularColoriGLint value): void SetemiCCiVeColor(GLfl0at valuel, GLfloat valuez, GLfloat value3,GLfloat value4i); GLfloat GetemissiveColoriGLint value) ; void SetshininessíGLfloat valueil; GLfloat Getshininecsil; void SettransparencyiGLfloat v a l u e l ) ; GLfloat GettransparencyO; Material (I ; -Material (I : void Setid (GLint value) : GLint GetidO; void SetpathTextUle(String value); String GetpathTextureO;

virtual void AlgoritmoInterfaz i QLfloat valuel , QLfloat value2 , QLfloat value3 , QLfloat value4 , QLfloat value5 , QLfloat value6 I = O; 1;

// Código del Archivo CAlgorl.hpp #ifndef -CAlgorl #define -CAlgorl #include “Meterial.hpp” clase CAlgorl : public Material { public:

138

Page 161: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

CAlgOrl 1 ) i virtual -CAlgorl í ) ; virtual void Setradius ( GLfloat valuel , QLfloat value2 , GLfloat value3 ,

void Algoritmolnterfaz [ GLfloat valuel , GLfloat value2 , GLfloet value3 , GLfloat value4 , GLfloat value5 , GLfloat Value6 ) = O;

GLfloQt value4 , GLfloat value5 , QLfloat value6 ) ;

#endif 1;

// Código del Archivo CAlgorl.cpp

I 1

#include "CA1gorl.h" CAigOrl::CAlgorl( 1 {

CAlgor1::-CAlgorlí ) {

void CAlgOr1::AlgoritmoInterfaz ( GLfloet valuel , QLfloat value2 , QLfloat value3 , GLfloat value4 , GLfloat value5 , GLfloat value6 ) (

Setradius~valuei.value2,value3~v~lue4,value5,valueS~; 1

// Código del Archivo CAlgor2.hpp tifndef -CAlgOrZ #define _CAlgor2 #include "Yateria1,hpp" clase CAlgorZ : public Material { public:

CAlgor21 i i virtual -CAlgor2 I I ; virtual void Setlineas ( QLfloat valuel , QLfloet value2 , QLfloat value3

void Algoritmolnterfee ( QLfloat valuel , QLfloat value2 , QLfloat value3 QLfloat value4 , QLfloat value5 , QLfloat value6 ) - 0 1

QLfloat value4 , QLfloat value5 , QLfloat value6 ) ;

Uendff 1 1

// Código del Archivo CAlgor2.cpp #include "CAlgor2.h" CAlgor2 : :CAlgor2 ( 1 {

CAlgor2 : : -CAlgor2 ( 1 {

void CAlgor2::Algoritmo1nterfaz 1 QLfloat valuel , QLfloat value2 , GLfloat value3 , GLfloat value4 , GLfloat value5 , GLfloat value6 ) {

I I

Setlineaelvaluel,velue2.value3.value3,value4,v~lu~5,valueS~; 1

// Código del Archivo CAlgor3.hpp Uifndef -CAlgor3 #define _CAlgor3 #include "Material.hpp" class CAlgor3 : public Material { public :

CAlgor31 I ; virtual -CAlgor3 ( 1 : virtual void Setpoints ( QLfloat valuel , GLfloet value2 , GLfloat value3 ,

void Algoritmolnterfaz I GLfloat valuel , GLfloat Value2 , GLfloat value3 , GLfloet value4 , GLfloat value5 , QLfloat value6 - (I;

GLfloat value4 , GLfloat value5 , QLfloat value6

#endif 1;

139

Page 162: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

// Código del Archivo CAlgor3.cpp #include "CAlgor3.h" CAlgor3 : : CAlgor3 ( I {

CAlgor3: : -CAlgor3 ( ) (

void CAlgor3::Algoritm01nterfaz í GLfloat valuel , GLfloat value2 , GLfloat value3 , GLfloat value4 , GLfloat value5 , GLfloat value6 ) (

> ~etpointslvaluel,value2.value3.value3,v~lu~4,valu~S,v~lu~S~;

1

// Código del Archivo ATorus.hpp #include cString.h> #if !definedi-Material) #include "CA1gOrl.h" #define -Material #include ',Material.hpp' #endif #if !definedl-Transform) U include '"Transform.hpp' #define -Transform #include 'Trancform.hpp" #endif class ATorus: public CAlgorl, public Transform ( private :

String name; GLint id; GLint index; GLfloat interiorRadius; GLfloat exteriorRadius;

void SetnamelString value); String Getnamell; void Setid(GLint value); GLint GetidO; void SetindexlGLint value); GLint Getindex0 ; ATorus I I :

public:

-ATOTUS 1 ) ; void Setradius(GLf1oat valuel, GLfloat valuez, GLfloat value3, GLfloat value4, GLfloat

values, GLfloat value61; GLfloat Getradiusll; void SetexteriorRadiusiGLfloat valuei; GLfloat GefexteriorRadiusO; ATorue(GLf1oat valuel, GLfloat valueil;

// void SetpointsIGLfloat valuei, GLfloat value2, GLfloat value3, GLfloat value4. GLfloat values, GLfloat values)( )

// void Setlineas(GLf1oat valuel, GLfloat value2, GLfloat value3, GLfloat value4. GLfloat values. GLfloat value6)( )

AVertex + Getpointclint indice)( return NULL;)

Line Getlineaslint indice)( return NULL;) 1;

// Código del Archivo ABaseCyl.hpp #include cvcl.hs #include cString.h> #if !defined(-Material) #include "CAlgOrl. h" #define -Material #include "Material.hpp" #endif #if !defined(-Transform) # include "Transform.hpp" #define -Transform #include "Transforrn.hpp" #endif class ABaseCyl: public CAlgorl, public Transform ( private : GLfloat radius;

140

Page 163: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

GLfloat heighr; string name: GLint id; GLint index;

void setnamel5tring value); string Getname i I ; void SetidlGLint value);

void SetindexiGLint value):

public:

GLint GetidO;

GLint GetindexO; void SetradiuslGLfloat valuei, GLfloat value2, GLfloat value3, GLfloat value4. GLfloat

values. GLfloat value6) i GLf loat Getradius ( 1 ; void SetheightlGLfloat value); GLfloat Getheight 1 1 ; ABaseCyll) ; -ABaseCyl I I ; ABaseCyl(GLf1oat YBlue1. GLfloat Value2);

/ / void SetpointsiGLfloat valuei, GLfloat value2, GLfloat value3, GLfloat value4. GLfloat values. GLfloat value6)( ]

/ / void SetlineasiGLfloat valuei, GLfloat value2. GLfloat value3, GLfloat value4, GLfloat values, GLfloat value6)( )

Avertex * Getpointslint indice)( return NULL;)

Line Getlineas(int indice)( return NULL;) 1;

// Código del Archivo APolyhedron.hpp #include <String.h> #if IdefinedIMaterial) #include .CAlgorl.h" #define Material #include "Material.hpp" #endif #if !defined(-Transform) # include "Transf0rm.hpp" #define -Transform #include ',Trancform.hpp" #endif class APolyhedron: public CAlgOr1, public Transform ( private:

sering name; GLint id: GLint index; GLfloat radius;

void Setnamelstring value); String GetnameO; void SetidlGLint value); GLint GetidO; void SetindexlGLint value); GLint Getindex0 ; APOlyhedrOn ( 1 ; -APolyhedron I ) ; void SetradiusIGLfloat valuel. GLfloat value2. GLfloat value3, GLfloat value4, GLfloat

values, GLfloat value6); GLfloat Getradiusil ; APolyhedroniGLfloat value);

public :

// void SetpointsIGLfloat valuei, GLfloat valuei, GLfloat value3, GLfloat value4. GLfloat values, GLfloat value6l( )

/ / void SetlineasIGLfloat valuel, GLfloat value2, GLfloat value3. GLfloat value4. GLfloat value5. GLfloat value6)( )

Avertex * Getpointslint indice)( return NULL;)

Line Getlineaslint indice)( return NULL;] 1 ;

141

Page 164: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caco de Prueba 4

// Código del Archivo Points.hpp #include cvcl.hs #include rString.h> #include cGl\glu.h> #include <Gl\glaux.h> #include <vector.hs #if !defined(-Material) #include mCAlg~r3.h" #define -Material #include "Materia1,hpp" #endif #if !defined 1-Transform) U include 'Transform.hpp' #define -Transform #include 'aTrans€orm.hpp" #endif #if !definedl-AVertex) # include "AVertex.hpp" #define Avertex #include "AVertex.hpp" #endif class Points : public CAlgor3, public Transform { private:

String name; GLint id; GLint index; Avertex *auxi;

/ / vector cAVertexs puntos; public :

int indp; Points ( 1 ; -Points I I ; void SetnamelString value); String GetnameO; void Setid(GLint value) ; GLint GetidO; void SetindexIGLint value): GLint Getindexll; void Setpoints(GLf1oat valuel, GLfloat valuei, GLfloat value3, GLfloat value4,

values, GLfloat value.5) ; Avertex * Getpointslint indicel; GLint GetSizeVectorO;

/ / void Setradius(GLf1oat valuel. GLfloat valuei. GLfloat value3. GLfioat GLfloat value5, GLfloat value61 ( ) / / void Setlineas(GLf1oat valuel, GLfloat valuei. GLfloat value3. GLfloat GLfloat value5. GLfloat valueól( ) Line Getlineaslint indice)( return NULL;)

1 ;

// Código del Archivo Line.hpp #include <vcl.h> #include sString.h> #include <Gl\glu.h> #include <Gl\glaux.h> #if !defined(-Material) #include "CAlgor3.h" #define -Material #include "Mbterial.hpp" #endif #if !defined(-Transform1 U include "Transfarm.hpp" #define Transform #include "Transform.hpp'' #endif #if !defined(-AVertex) U include "Avertex. hpp" #define A v e r t e x #include "AVertex.hpp" #endif class Line : public CAigor3, public Transform { privare: Avertex pointl;

GLfloat

value4,

value4,

142

Page 165: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

Avertex point2; String name; GLint id; GLint index;

void Setnameistring valuel; String GetnameO; virtual -Line0 ; LineIGLfloat valu.1. GLfloat value2, float value3. GLfloat value4, GLfloat value5.

Line ( 1 ; void SetidIGLint value); GLint GetidO; void Setindex(GLint value); GLint Getindex(); void Setpoints(GLf1oat valuel, GLfloat value2. GLfloat value3, GLfloat value4, GLfloat

values, GLfloat value6); Avertex * GetpointsO; void SetpointZ(GLf1oat valuel, GLfloat valuei, GLfloat value)); Avertex * Getpoint20;

public:

GLfloat value61 ;

/ / void Setradius(GLf1oat valuel, GLfloat value2, GLfloat value3, GLfloat value4. GLfloat values, GLfloat value6)( ) // void Setlineas(GLf1oat valuel, GLfloat value2, GLfloat value3. GLfloat value4, GLfloat value5, GLfloat value6)( ) Line Getlineas(int indice)( r e t u r n NULL;)

1;

// Código del Archivo Triangle.hpp #include cvcl.h> #include cString.h> #include cGl\glu.h> #include <Gl\glaux.h> #if !def ined(-Linel # include "Line.hpp" #define -Line #include 'Line.hpp" #endif #if !defined(-Material) #include "CAlgor2.h" #define -Material #include "Material.hpp" #endif #if !defined(-Transform) U include "Transform.hpptr #define -Transform #include "Transform.hpp" #endif class Triangle : public cAlgor2. public Transform ( private :

Line lineal; Line lineai; Line linea3; String name; GLint id; GLint index;

void Setname(String value); String Getname(); Triangle ( 1 ; -Triangle ( I ; void Setid(GLint value); GLint GetidO; void Setindex(GLint value): GLint GetindexO; void SetlineasiGLfloat valuel. GLfloat value2. GLfloat value3, GLfloat value4. GLfloat

Line Getlineasiint indice); void SetlineaZiGLfloat valuel. GLfloat value2. GLfloat value3. GLfloat value4, GLfloat

public:

values. GLfloat value6);

values, GLfloat value6);

143

Page 166: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Anexo G. Código del Caso de Prueba 4

Line f Getlineail); void Setlinea3lGLfloat valuei. GLfloat vaiuei. GLfloat value3, GLfloat value4, GLfloat

value5. GLfloat value6); Line * Getlinea30;

// void SetpointslGLfloat valuel. GLfloat value2. GLfloat value3. GLfloat value4, GLfloat value5. GLfloat value6){ )

/ / void SetradiuslGLfloat valuel. GLfloat valuei. GLfloat value3, GLfloat value4, GLfloat value5, GLfloat value6)( ]

AVertex * Getpointslint indice){ return NULL;)

1;

// Código del Archivo Material.hpp #include cvcl.h> #include <String.hs #include <Gl\glu.hs #include <Gl\glaux.h> #if !defined(Material) #include aCAlgor2.h" #define -Material #include 'Material.hpp" #endif #if !defined(-Transform) U include "Transforrn.hpp" #define -Transform #include "Trancform.hpp" #endif #if !defined(Line) # include 'Line.hpp" #define -Line #include "Line. hpp" #endif class CPolygon : public CAlgor2, public Transform ( private:

Line lineas [ S o l ; String name; GLint id; GLint index;

void SetnamelString value); string GetnameO; CPolygon I ) ; -CPolygon I ) i void Setid(GLint value) ; GLint Getid0 ; void SetindexlGLint value); GLint Getindex0 ; void CetlineaslGLfloat valuel, GLfloat valuei, GLfloat value). GLfloat value4, GLfloat

Line Getlineaslint indice);

public:

value5, GLfloat value6);

/ / void SetoointsIGLfloat v a l u e ~ , GLfloat va1ue2, GLfloat vaiue3, GLfloat value4. . . GLfloat values, GLfloat value6){ )

// void SetradiuslGLfloat valuel, GLfloat value2, GLfloat value3. GLfloat value4. AVertex * Getpoincslint indice)( return NULL;)

GLfloat values. GLfioat value6)( ) 1;

144

Page 167: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Referencias

REFERENCIAS

[AbraOl]

[Bera03]

[Biem92]

[Bigg891

[Bran981

[Bria96]

[Brit951

[Cale02]

[ Card041

[Chid941

[ChuWOO]

Alain Abran, James W. Moore, Pierre Bourque, Robert Dupuis y Leonard L. Tripp; Guide to the Software Engineering Body of Knowledge; IEEE Trial Version 0.95; http://www.swebok.org; 2001

Edward V. Berand; Metrics for Object-Oriented Software Engineering; The Object Agency, Inc.; 2003

James M. Bieman; “Deriving Measures of Software Reuse in Object Oriented Systems”; Proceedings of the Workshop on Formal Aspects of Measurement; Springer-Verlag; Londres, Inglaterra; 1992

Ted J. Biggerstaff y Alan J. Perlis; Software Reusability: Concepts and Models; Addison Wesley; 1989

John Brant, Brian Foote, Ralph E. Johnson y Donald Roberts; “Wrappers to the Rescue”; Proceedings of the European Conference on Object-Oriented Programming, ECOOP ’98; Bruselas, Bélgica; 1998

Lionel BnAd, Sandro Morasca y Victor R. Basili; “Property-Based Software Engineering Measurement”; ZEEE Transactions on Software Engineering, No I ; 1996

Fernando Brito e Abreu, Miguel Goulao y Rita Esteves; “Toward the Design Quality Evaluation of Object-Oriented Software Systems”; Proceedings of the 5th International Conference on Software Quality; Austin, Estados Unidos; 1995

Coral Calero; Métricas para la Calidad de los Sistemas de Información; Curso 2002/2003, Técnicas informáticas Avanzadas; Departamento de Informática, Universidad de Castilla - La Mancha; 2002

Leonor A. Cárdenas; Refacíorización de Marcos Orientados a Objetos para Reducir el Acoplamiento Aplicando el Patrón de Diseño Mediator; Tesis de Maestría; Departamento de Ciencias de la Computación, Centro Nacional de Investigación y Desarrollo Tecnológico; 2004

Shyam R. Chidamber y Chris F. Kemerer; “A Metrics Suite for Object Oriented Design”; IEEE Transactions on Software Engineering, No. 6, Vol. 20; 1994

William C. Chu, Chih-We¡ Lu, Chih-Peng Shiu y Xudong He; “Pattem- Based Software Reengineering: a Case Study”; Journal of Software Maintenance: Research and Practice, No 12; 2000

I

145

Page 168: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Referencias

[Diazo41

[Delfü4]

[FayaOO]

[Fent94]

[Fent97]

[Foot881

[Foot941

[Foot951

[Fowl991

[Frag04]

[Frag04a]

Ariadna J. Diaz; Entorno de Graficación y Generación de Modelos 2 0 y 30 para Aplicaciones de Visión Artificial; Tesis de Maestría; Departamento de Ciencias de la Computación, Centro Nacional de Investigación y Desarrollo Tecnológico; 2004

Sheila L. Delfin; Sistema para el Descubrimiento y publicación de Servicios Disponibles a través del Web; Tesis de Maestría; Departamento de Ciencias de la Computación, Centro Nacional de investigación y Desarrollo Tecnológico; 2004

Mohamed E. Fayad y Ralph E. Johnson; Domain-Specific Application Frameworks; Wiley Computer Publishing, John Wiley & Sons, Inc.; 2000

Norman E. Fenton; “Software Measurement: A Necessary Scientific Basis”; IEEE Transactions on Software Engineering, No 3; 1994

Norman E. Fenton y Shari L. Pfleeger; Software Metrics: A Rigorous and Practical Approach; PWS Publishing; 1997

Brian Foote; Designing to Facilitate Change with Object-Oriented Frameworks; Tesis de Maestria; Department of Computer Science, University of Illinois at Urbana Champaign; 1988

Brian Foote y William F. Opdyke; “Lifecycle and Refactoring Patterns that Support Evolution and Reuse”; Proceedings of the First Conference on Pattern Languages of Programs, Plop ’94; Monticello, Estados Unidos; 1994

Brian Foote; An Object-Oriented framework for reflective meta-level architectures; Tesis de Doctorado; Department of Computer Science, University of Illinois at Urbana Champaign; 1995

Martin Fowler, Kent Beck, John Brant, William F. Opdyke y Donald Roberts; Refactoring, improving the Design of Existing Code; Addison Wesley, 1999

O h i a G. Fragoso, René Santaolaya, Isaac M. Vásquez y Manuel Valdés; “Frameworks as Web Services”; Proceedings of The 2004 International Conference on Computational Science and Its Applications - ICCSA 2004; Springer-Verlag LNCS 3046; Asís, Italia; 2004

O h i a G. Fragoso, René Santaolaya, Isaac M. Vásquez, Manuel Valdés y Luis E. Santos; “Servicios Web para el Desarrollo de Software”; Memorias de la 3ra Conferencia iberoamericana en Sistemas, Cibernética e Informática, CISCI 2004; Orlando, Estados Unidos; 2004

146

Page 169: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Referencias

[Free871 Peter A. Freeman; “A Perspective on Reusability”; IEEE Tutorial: Software Reusabiliy, IEEE Computer Sociefy Press; 1987

Erich Gamma, Richard Helm, Ralph E. Johnson, y John Vlissides; Design Patterns: Eiements of Reusable Software Architecture; Addison Wesley; 1995 Francisco J. Garcia, José M. Marqués y Jesús M. Maudes; Andisis y Diseño Orientado al Objeto para Reutilización; Reporte Técnico, TR-GIRO-O 1 - 97V2.1.1; Universidad de Valladolid; 1997

Alejandra Garrido y Ralph E. Johnson; “Refactoring C with Conditional Compilation”; Proceedings of the 18th IEEE International Conference on Automated Software Engineering, ASE 2003; Montreal, Canadá; 2003

Alejandra Garrido; Program Refactoring in the Presence of Preprocessor Directives; Tesis de Doctorado; Department of Computer Science, University of Illinois at Urbana Champaign; 2004

ISO/IEC Standard 9126; IS0 9126 Software Product Evaluation - Quality Characteristics and Guidelines for their Use; Ginebra, Suiza; 1991

Ivar Jacobson, Magnus Christerson, Patrik Jonsson y Gunnar Overgaard; Object-Oriented Sofmare Engineering: A Use Case Driven Approach; Addison Wesley; 1992

Java - net; Java Compiler Compiler (JavaCC) - The Java Parser Generator; https://javacc.dev.java.net/; 2003

Ralph E. Johnson y Brian Foote; “Designing Reusable Classes”; Journal of Object-Oriented Programming, No. I ; 1988

Ralph E. Johnson y William F. Opdyke; “Refactoring and Aggregation”; Object Technology for Advanced Software; Springer-Verlag LNCS 742; 1993

Joshua Kerievsky; DRAFT of Refactoring to Patterns, v 0.17; Industrial Logic, Inc; to be Published by Addison Wesley in 2004; 2003

Robert C. Martin; “The Interface Segregation Principle”; C++ Report; 1996

[Gamm95]

[Garc97]

[Gam031

[Gam041

[ISO91]

[Jaco921

[Java031

[John881

[John931

[Ken031

[Mart961

[Meye981 Bertrand Meyer; Object-Oriented Software Construction; Prentice Hall; 1998 !!

[OCin96] Me1 Ó Cinnéide; “Towards Automating the introduction of the Decorator Pattern to Avoid Subclass Explosion”; Proceedings of the Object-Oriented Evolution and Reengineering Workshop. OOPSLA ‘96; San José, Estados Unidos: 1996

147

Page 170: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Referencias

[OCin99]

[OCinn99a]

[OCinnOO]

[OCinOOa]

[OCinOl]

[OKefO3]

[OPdy921

[OPdy931

[Robe961

[Robe971

[Robe981

Me1 Ó Cinnéide y Paddy Nixon; “Program Restructuring to introduce Design Patterns”; Proceedings of the IEEE International Conference on Software Maintenance; Oxford, Inglaterra; 1999

Me1 Ó Cinnéide y Paddy Nixon; “Automated Application of Design Patterns to Legacy Code”, Proceedings of the Workshop on Experiences in Object- Oriented Reengineering, European Conference on Object-Oriented Programming, ECOOP ‘99; Lisboa, Portugal; 1999

Me1 Ó Cinnéide y Paddy Nixon; “Composite Refactorings for Java Programs”; Proceedings of the Workshop on Formal Techniques for Java Programs, European Conference on Object-Oriented Programming, ECOOP ’00; Sophia Antipolis y Cannes, Francia; 2000

Me1 Ó Cinnéide; “Automated Refactoring to introduce Design Patterns”, Proceedings of the International Conference on Software Engineering, ICSE 2000; Limerick, Manda; 2000

Me1 Ó Cinnéide; Automated Application of Design Patterns: a Refactoring Approach; Tesis de Doctorado; Department of Computer Science, University of Dublin, Trinity College; 200 1

Mark O‘Keeffe y Me1 Ó Cinnéide; “A Stochastic Approach to Automated Design improvement”; Proceedings of the International Conference on the Principles and Practice of Programming in Java; Kilkenny City, Irlanda; 2003

William F. Opdyke; Refactoring Object-Oriented Frameworks; Tesis de Doctorado; Department of Computer Science, University of Illinois at Urbana Champaign; 1992

William F. Opdyke y Ralph E. Johnson; “Creating Abstract Superclasses by Refactoring”; Proceedings of the CSC ’93: 1993 ACM Computer Science Conference; Indianápolis, Estados Unidos; 1993

Donald Roberts y Ralph E. Johnson; “Evolving Frameworks, a Pattern Language for Developing Object-Oriented Frameworks”; Pattern Languages ofPrograms, PLOP ’96; Allerton Park, Estados Unidos; 1996

Donald Roberts, John Brant y Ralph E. Johnson; “A Refactoring Tool for Smalltalk”; Theory and Practice of Object Systems; 1997

Donald Roberts, John Brant y Ralph E. Johnson; “Why every Smalltalker should use the Refactoring Browser”; Smalltalk Report; 1998

148

Page 171: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Referencias

[Robe991

[Rodr04]

[Santo21

[Santo31

[Sant03a]

[Sant03b]

[Sant03c]

[Santo41

[Sant04a]

Donald Roberts; Practical Analysis for Refactoring; Tesis de Doctorado; Department: of Computer Science, University of Illinois at Urbana Champaign;’ 1999

Juan J. Rodriguez; Integración de la Funcionalidad de Framework Orientados a Objetos; Tesis de Maestría; Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico; 2004

René Santahaya; Modelo de Representación de Patrones de Código para la Constrücción de Componentes Reusables; Tesis de Doctorado; Departamento de Ciencias Computacionales, Centro de Investigación en Computación, IPN; 2002

René Santaolaya, O h i a G. Fragoso, Joaquín Pérez y Lorenzo Zambrano; “Restructuring Conditional Code Structures Using Object Oriented Design Patterns”; Proceedings of The 2003 International Conference on Compuíational Science and Its Applications - ICCSA 2003; Springer-Verlag LNCS 2667; Montreal, Canadá; 2003

René Santaolaya, O h i a G. Fragoso y Manuel Valdés; “Método de Refactorización de Frameworks: Separación de Interfaces”; Memorias del I Orno Congreso Internacional de Investigación en Ciencias Computacionales, CIZCC ’2003; Oaxtepec, México; 2003

René Santaolaya, O h i a G. Fragoso, Luis E. Santos y Manuel Valdés; “Adaptación de Interfaces de Marcos de Aplicaciones Orientados a Objetos, Utilizando el Patrón de Diseño Adapter”; Memorias de la Decimocuarta Reunión de Otoño de Comunicaciones, Computación y Electrónica, IEEE ROC&C’2003; Acapulco, México; 2003

René Santaolaya, O h i a G. Fragoso y Manuel Valdés; “Refactorización de Frameworks por la Separación de Interfaces”; Memorias de la Decimocuarta Reunión de Otoño de Comunicaciones, Computación y Electrónica, IEEE ROC&C’2003; Acapulco, México; 2003

René Santaolaya, Olivia G. Fragoso, Manuel Valdés e Isaac M. Vásquez; “Preparing Frameworks to Become Web Services’’; Proceedings of the IADIS International Conference Applied Computing 2004; Lisboa, Portugal; 2004

René Santaolaya, O h i a G. Fragoso, Manuel Valdés, Isaac M. Vásquez y Sheila L. Delfín; “An Object-Oriented Metric to Measure the Degree of Dependency due to Unused interfaces”; Proceedings of The 2004 International Conference on Computational Science and Its Applications - ICCSA 2004; Springer-Verlag LNCS 3046; Asís, Italia; 2004

I

I1

149

Page 172: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Referencias

[Sant04b]

[Sant04c]

[Sant04d]

[Sant04e]

[Sosa041

[Szip99]

[Toku95]

[Toku99]

[Toku99a]

[TokuO 13

René Santaolaya, O h i a G. Fragoso, Manuel Valdés, Isaac M. Vásquez y Luis E. Santos; “Achieving Software Reuse Using the Interface Separation Principle of Object-Oriented Design”; Proceedings of The 8th World Multi- Conference on Systemics, Cybernetics and Informatics, SCI 2004; Orlando, Estados Unidos; 2004

René Santaolaya, Olivia G. Fragoso, Manuel Valdés, Isaac M. Vásquez y Luis E. Santos; “Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces”; Memorias de la 3ra Conferencia Iberoamericana en Sistemas, Cibernética e Informática, CISCI 2004; Orlando, Estados Unidos; 2004

René Santaolaya, Olivia G. Fragoso, Manuel Valdés y Leonor A. Cárdenas; “Using Design Patterns to Solve the interface Dependency Problem”; Memorias del I I vo Congreso Internacional de Investigación en Ciencias Computacionales, CIICC’2004; Tlalnepantla, México; 2004

Luis E. Santos; Adaptacibn de Interfaces de Marcos de Aplicaciones Orientados a Objetos por Medio del Patrón de Diseño Adapter; Tesis de Maestría; Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico; 2004

Víctor J. Sosa, Juan G. González, Xochitl Landa, Francisco Verduzco y Manuel Valdés; “Dynamic Configuration between Proxy Caches within an Intranet”; Proceedings of The 2004 International Conference on Computational Science and Its Applications - ICCSA 2004; Springer-Verlag LNCS 3046; Asís, Italia; 2004

Clemens Sziperski; Component Software: Beyond Object-Oriented Programming; Addison Wesley; 1999

Lance Tokuda y Don Batory; “Automated Software Evolution via Design Pattern Transformations”; Proceedings of the 3rd International Symposium on Applied Corporate-Computing; Monterrey, México; 1995

Lance Tokuda; Design Evolution with Refactorings; Tesis de Doctorado; Department of Computer Science, University of Texas at Austin; 1999

Lance Tokuda y Don Batory; “Automating three Models of Object-Oriented Software Evolution”; Proceedings of the Conference on O 0 Technologies and Systems, COOTS ’99; San Diego, Estados Unidos; 1999

Lance Tokuda y Don Batory; “Evolving Object-Oriented Design with Refactorings”; Automated Sofiware Engineering, No.& 200 1

150

Page 173: Método de Refactorización de Marcos de Aplicaciones ...20Man… · Refactorización de Marcos de Aplicaciones Orientados a Objetos por la Separación de Interfaces, me es grato

Referencias

[Vasq04] Isaac M. Vásquez; Generación de Servicios Web a partir de Sofhyare Legado; Tesis de Maestría; Departamento de Ciencias Computacionales, Centro Nacional de Investigación y Desarrollo Tecnológico; 2004

Sreenivasa Viswanadha; JavaCC Grammar Repository, C++ Grammar vf . I; http://www.cobase.cs.ucla.edu/pub/javacc/CPLUSPLUS.jj; Sun Microsystems Inc.; 1996

[Visw96]

[Zuse95] Horst Zuse; "Properties of Object-Oriented Software Measures"; Proceedings of the Annual Oregon Workshop on Sofhyare Metrics, A 0 WSM; Silver State Park, Estados Unidos; 1995

[Zuse98] Horst Zuse;l!A Framework of Sofmare Measurement; Walter de Gruytier; 1998

151