S.E.P. S.E.I.T. D.G.I.T. Centro Nacional de Investigación y Desarrollo Tecnológico CENIDET Ingeniería Inversa de Código Fuente en C++ para la Obtención de su Diseño TESIS Que para obtener el grado de . Maestro en Ciencias en Ciencias Computacionales presenta: MIGUEL HERNÁNDEZ VELÁZQUEZ Director de Tesis: M.C. MÁXIMO LÓPEZ SÁNCHEZ Codirector de Tesis: M.C. ISAAC ALBERTO PARRA RAMÍREZ DG'Tl s ~ p CENlDET CENTRO DE iNFORMAClON 03-0334 Cuernavaca, Morelos Agosto del 2003 Cuemavaca, Mor., a 18 de Agosto de 2003 Dr. Gerard0 Reyes Salgado Presidente de la'Academia de Ciencias Computacionales Presente 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 denominada: Ingeniería Inversa de Código Fuente en C++ para la Obtención de su Disetio, realizada por ei(ia) C. Miguel Hemández Velázquez, y habiendo realizado las mrrecciones que le fueron indicadas, acordamos no tener objeción para que se le conceda la autorización de impresión de la tesis. Sin otro particular, quedamos de usted Atentamente L a comisión de revisión de tesis Dr. René Sadtaolaya Salgado \ f - (M.c. Olivia FI *a@$ i Diaz /- \ Luis Liñán Garcia Codirector de tesis C.C.P. Dr. Rodolfo A Pazos Rangel, Jefe del Depto. de Ciencias Computacionales Lic. Olivia Maquinay Díaz, Jefe del Depto. de Servicios Escolares. C. Miguel Hemández Velázquez, alumno del programa de maestría. INTERIOR INTERNADO PALMIRA SIN, COL, PALMIRA, A.P. 5-164. CP. 62490,CUERNAVACA, MOR. - MÉXICO TELS. (777) 312 23 14,318 77 41. FAX (777) 312 24 34 FMAll nnio?Qrdrenidntr n m my Iu & % m 3 m % m m w ~ ~ ~ L í E m c x . 3 N t FORMULARIO C4 AUTORIZACIÓN DE IMPRESION DE TESIS Cuernavaca, Mor., a 19 de Agosto de 2003. C. Miguel Hemández Velázquez Candidato al grado de Maestro en Ciencias en Ciencias Computacionales Presente Después de haber atendido las indicaciones sugeridas por la Comisión Revisora de la Academia de Ciencias Computacionales en relación a su trabajo de tesis: Ingeniería Inversa de Código Fuente en C++ para la Obtención de su Diseño, 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. Jefe del Depto. de Ciencias Computacionales C.C.P. Lic. Ohia Maquinay Diaz, Jefe Depto. de Servicios Escolares INTERIOR INTERNADO PALMIRA S / N . COL. PALMIRA , A.P. 5-164. CP. 62490, CUERNAVACA. MOR. MÉXICO TELS.(777I312 2 3 1 4 . 3 1 8 7 7 4 1 . F A X í 7 7 7 i 312 2 4 3 4 ~ Para mís padres, para Ise, y . parachei Agradecimientos Quiero expresar mi mas sincero agradecimiento a todas las personas que de alguna manera contribuyeron para finalizar este proyecto de tesis (en la lista de abajo quizá no estén todas y cada una de ellas dado que mi memoria no es precisamente de elefante y ha pasado bastante tiempo); cada quién puso una roca o un granito de arena en la conversación, en el espaldarazo, en la crítica, en lo económico, en el saludo, en el enojo, tristeza o alegría justo en el momento indicado (el orden de aparición no indica el importancia necesariamente): A mi asesor Máximo López por toda la ayuda moral e incluso económica, consejo académico y disculpas aceptadas. Por ser un guía que no desdeña el trato humano. Por aprender a escuchar las ideas este inusual tesista. Vivan los vivos. A Javier Ortiz pues al inicio de la maestría su apoyo fue imprescindible para emprender el reto con ánimo y esperanza. Por las concienzudas y profundas pláticas de cómo mejorar varios aspectos de este condenado país. A René Santaolaya porque detrás de toda su bien ganada sapiencia existe un ser humano que finalmente también es capaz de escuchar. Gracias por ser un ejemplo para mi carrera profesional. La programación con objetos ya tienen sentido para mi al fin. A Olivia Fragoso, gracias por ser una parte decisiva en mi aspiración de entrar al centro. Gracias por ser una guía en muchos aspectos extra-académicos, pero principalmente por todo el consejo durante mi transición hacia la vida como padre. La Ingeniería de Software sípuede ser divertida e int&esante, siempre y cuando se tope uno con gente como Olivia y se platique al respecto. Al Dr. Pazos, por compartir largas conversaciones que permitieron abrir mi original ingenuo panorama sobre el conocimiento y uno que otro sabio consejo más. Por las verdaderas cátedras en el aula acerca de la Bases de Datos. Por el apoyo en general que me otorgó durante mi estancia. A mis compañeros de-generación: Isabel - por su confianza para platicar y su apoyo inicial Gustavo - por su transparencia y calidez humana Alberto por recordarme que la vida no debe ser tan complicada y por tener tan buenos gustos musicales Karina - por su sinceridad, femineidad y los Buffy. Laura - por mostrarme que una mujer puede representar un verdadero reto en el ámbito profesional, pero principalmente por Compartir con Michelle tantos momentos Abril - porque a pesar de tantos roces, logramos pintar una raya de respeto Javier - por ser un ejemplo de madurez y coraje deportivo, por mostrar un espíritu ganador todo el tiempo Carlos - por mostrar una respetable amistad y por ser un ejemplo de dedicación al estudio Osslan - por no irle al América, por tocar tan bien la guitarra y ser un ejemplo de pasión por algo musical, por su espíritu tan alegre Chícharo - por su nobleza desmedida, por apoyarme cuando se prestó la oportunidad Omar - por su franqueza a hablar y por su admirable capacidad para programar René - por llegar a ser un amigo al fin Juan - por brindar su sincera amistad y cuidar de Michelle incondicionalmente - Desde luego a la SEP y en especial al COSNET por prestar la ayuda económica sin la cuál este proyecto simplemente no se hubiera logrado. Gracias. I N G E N ~ E R ~INVERS A A DE CÓDIGO FUENTE EN c++PARA LA OBTENCIÓN DE SU DISENO Introducción El tema central del presente trabajo se enfoca hacia la aplicación de ingeniería inversa para recuperar diseños de software. Lo anterior, debido en gran parte a que el ingeniero de software frecuentemente echa mano de herramientas automatizadas que recuperan diseños para mantener y documentar sistemas de software, reduciendo la complejidad del entendimiento de código fuente. Las herramientas en el mercado que realizan ingeniería inversa de sistemas orientados a objetos generalmente son costosas y presentan una peculiar limitación: a últimas fechas se ha dejado de lado la recuperación del diseño detallado de los métodos de clases. Se pretende que SOODA', una herramienta que ayuda a modelar sistemas orientados a objetos, sea capaz de recuperar el diseño de clases y el diseño detallado de métodos desde software implementado en C++,a partir de la creación e integración de un mecanismo de ingeniería inversa. Es necesario estudiar varios temas para la realización de este proyecto: las tecnologías de objetos que involucran a los atrones de diseño y el desarrollo de software con la MFC2; diagramas de clases del UML y ' diagramas . del método de Warnier; la traducción de r: lenguajes libres de contexto y el lenguaje de programación C++. El uso de tecnologías de objetos es fundamental para poder incorporar a SOODA la capacidad de recuperar diagramas. El núcleo de SOODA seguirá bajo la arquitectura MFC pero el uso de patrones de diseño facilitará el diseño e implementación de clases reusables que permitan construir diagramas a partir del análisis de código fuente. El diagrama de clases del UML y los diagramas de Warnier, serán la notación base para representar respectivamente los diagramas con las perspectivas estática y dinámica del diseño recuperado desde código fuente en C++. La teoría de traducción de lenguajes permitirá identificar un formalismo para traducir de manera eficaz el código fuente en C++ hacia el conjunto de diagramas mencionados anteriormente. Aunado a esta base formal se usará la herramienta ANTLR4 para constxuir el núcleo traductor de la herramienta. i SOODA es producto dc la I& "Modelado Oricniado a Objeior". dcl grupa dc ingenieria de Solbarc. dcl Centro Nacional de lnvesligacibn y Desanollo Tecnológico, en Cuemavaca, Morelos. Mexico. 2 Bibliolcca de Clases Base dc Microsafl 1 Lcnguajc Unificado de Modelado 4 Anoiher Tool for Language Recognition INGENlERiA INVERSA DE CÓOIGO FUENTE EN c++PARA LA OBTENCIÓN DE SU DISENO En el presente trabajo de tesis se construye una herramienta que permite realizar ingeniería inversa de código fuente en C++ para obtener las vistas estática y dinámica de su diseño en forma de diagramas de clases del UML y en diagramas de Wamier respectivamente. En el Capítulo 1 se mencionan, analizan y comparan los trabajos relacionados, se comentan la problemática resuelta, la hipótesis de investigación, los beneficios esperados, los alcances y las limitaciones de la herramienta. El Capítulo 2 revisa el marco teórico que envuelve al trabajo. En el Capítulo 3 trata sobre el modelo conceptual del sistema. El Capítulo 4 describe la construcción de la herramienta y las pruebas realizadas. Finalmente, el Capítulo 5 discute los resultados y conclusiones obtenidas, los beneficios directos y los trabajos futuros. Los tipos de letra varían deliberadamente en el contenido del documento. El tipo de letra base es Tintes New Roman, el tipo de letra para las ilustraciones y tablas es A r i d y el tipo de letra para porciones de código es Courier New. <. 11 ,<' .'.I<., INGENIER~AI NVERSA DE Cooico F U E N TE EN c++PARA LA O Q T E N C I ~ N DE SU DISECO CONTENIDO GENERAL ....................................... ...................................... ...I VI1 Capítulo I . Conceptos Generales 1.1 1.2 1.3 Objetivo de la Tesis .................................................................................. 1.4 Hipotesis ...................... 1.5 Beneficios Esperados 1.6 1.i ........................ 1.8 Referencias.. ..... I . ....................................... 8 ...................................... IO Antecedentes .................... 1 ................. Definiciones de Conceptos Centrales El Lenguaje Unificado de Modelado. Diseño Detallado en InverDDVi ....... Base Teórica del Análisis de Código ................. ........................... Construcción Automática de Analizadores Sint Patrones de Diseño Orientados a Objetos ....................................... Referencias ................................................................................................................... 32 35 Capítulo 2. Marco Teórico 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 Capítulo 3. El Modelo Conceptual del Sistema 3.1 3.2 3.3 3.4 3.5 3.6 3.7 Introducción ................. ................ Arquitectura de InveS Diagrama de Clases d Aspectos de Diseño Orientado a Objetos.......... Los Analizadores de Código Fuente ....................................... Interaccion con InverDDVi ............................................................................................................ Referencias................... ................................ ............. . I 57 75 76 Capítulo 4. Desarrollo y Pruebas de la Herramienta 4.1 4.2 4.3 4.4 4.5 Iniroducción 79 Manejo de la lnterfaz Gráfica de Usuario ........ 79 Implementación de los Analizadores de Códig ................................................................. 86 Pruebas ....................... ....................................... 95 Referencias ........................... ............................................................................ 1 I8 Capítulo 5 . Conclusiones 5.1 5.2 5.3 5.4 Análisis de los Resultados Obtenidos ................ ........................... ..................... Conclusiones ...................... ............................................................................ Trabajos Futuros...'. ...... ................ Refcrencias .................................................................................................................................... ~ ... 111 121 122 123 123 INGENlERiA INVERSA DE CODIGO F UENTE EN c* PARA LA OBTENCION DE SU DISENO ÍNDICEDE FIGURAS Figura Página Figura 1.1 Proceso básico de ingeniería inversa de Byrne 3 Figura 1.2 Proceso básico de recuperación de diseños de Biggerstaff 4 Figura 1.3 Diagrama de actividades UML de la metodología de solución empleada II Figura 2.1 Áreas de aplicación actuales de la Ingeniería Inversa de Software 16 Figura 2.2 Proceso conceptual de una traducción dirigida por la sintaxis 27 Figura 2.3 Ejemplo de una estructura Composite: la jerarquía de figuras geométricas 33 Figura 2.4 Estructura general del patrón de diseño Composite 34 Figura 2.5 Estructura general del patrón de diseño Builder 35 Figura 3.1 Arquitectura de InverSOODA vista por capas de servicios 40 Figura 3.2 Diagrama de clases de InverSOODA 41 Figura 3.3 Relación entre el documento y la vista de una aplicación MFC 43 Figura 3.4 Diagrama de clases con los patrones de diseño Composite, Iterator y Visitor embebidos en la arquitectura de InverSOODA 46 Figura 3.5 Construcción asíncrona del diagrama de clases 51 Figura 3.6 Construcción sincrona del diagrama de clases 52 Figura 3.7 Diagrama de clases del UML del patrón del diseño Builder embebido en la arquitectura de InverSOODA 53 Figura 3.8 Diagrama de secuencias del UML de los objetos en el patrón Builder 54 Figura 3.9 Patrón de diseño Command embebido en la arquitectura de InverSOODA 57 Figura 3.10 Ejemplo de archivo de especificación gramatical para ANTLR 59 Figura 3.1 1 Autómata reconocedor de palabras reservadas 62 Figura 3.12 Autómata reconocedor de caracteres en blanco 63 Figura 3.13 Autómata reconocedor de comentarios del tipo doble - diagonal 63 Figura 3.14 Autómata reconocedor de comentarios del tipo diagonal - estrella 64 Figura 3.15 Autómata reconocedor de diversos caracteres simples 64 Figura 3.16 Autómata reconocedor de caracteres literales 65 Figura 3.17 Autómata reconocedor de cadenas literales 65 iv , :. .". , 4 ,..I. ..'U, INGENlERiA INVERSA DE CÓDIGO FUENTE EN c* ,1 PARA LA OBTENCION DE SU DISENO Página Figura Figura 3.18 Autómata que reconoce caracteres de escape 66 Figura 3.19 Autómata reconocedor de dígitos decimales 66 Figura 3.20 Autómata reconocedor de números enteros 67 Figura 3.21 Autómata reconocedor de identificadores 67 Figura 3.22 Traducción entre una clase en código fuente hacia una figura 73 Figura 3.23 Ejemplo de árbol sintáctico de derivación con acciones semanticas 73 Figura 3.24 Orden de ejecucióii acciones semánticas y sus correspondientes efectos en la traducción 74 Figura 3.25 Interacción de la herramienta InverDDVi en el proceso de recuperación de diseño detallado de métodos de c!ases 75 -? I 1 1 Figura 4.1 Cambios en 1% barras de modelado y de herramientas de SOODA 79 Figura 4.2 Interfaz gráfica de usuario de InverSOODA 80 Figura 4.3Cuadro de diálogo que pregunta si se inicia otro proceso de ingenieria inversa 81 Figura 4.4 Cuadro de diálogo para seleccionar el archivo que contiene el código fuente en C++ sobre el cual se aplicará la recuperación de diseño 82 Figura 4.5 Cuadro de diálogo que indica al usuario la recuperación con éxito de un diseño desde código fuente Figura 4.6 E'em I 1 metodo de clase &un d\&rama de Wamier que corresponde al diseño detallado de un Figura 4.7 Instantánea de la interfaz utilizada cuando de acciona la recuperación del diseño detallado de un midodo en particular Figura 4.8 Métodos y atributos de la clase InverSoodaDiagramaBuilder usados en 10s mecanismos de ingenieria inversa Figura 4.9 Diagrama de clases generado de manera asÍncrona por niedio de la barra de modelado de InVerSOODA Q U I4.10blamama generado para i a función Context0::interaciua 81 84 85 90 96 97 Figura 4.11 Diseño detallado del método Suina::Calcula 98 Figura 4.12 Diseña detallado del método Media::Calcula 98 I Figura 4.13 Diserio detallada del rnátodo Desviación::Calcula 99 Figura 4.14 Pantalla de salida en la ejecución del código gcnerado con los mecanismos de ingenieria directa de InverSOODA I04 INGENlERiA INVERSA DECODIGOFLJENTE EN c* PARA LA OBTENCION DE SU DISENO Figura Página Figura 4.15 Diagrama de clases recuperado con InverSOODA: despliegue de las clases BDSys y de BDMenu 1o9 Figura 4.16 Diseño detallado recuperado del método aStratl ::getnum() 110 Figura 4.17 Diseño detallado recuperado del método aSfratl::pidevar() I10 Figura 4.18 Diseño detallado recuperado del método aStrat1;:pidevaK) 111 Figura 4.19 Diseño detallado recuperado del método aStratl::pidegrupo() 111 Figura 4.20 Diseño detallado recuperado del método cStrl I::Algor¡tmoDeInterFaz() 112 Figura 4.21 Diseño detallado recuperado del método cStrlZ::AlgoritmoDeInterfaz() 112 Figura 4.22 Diseño detallado recuperado del método cStrl3::AlgoritmoDeInterfaz() 113 Figura 4.23 Diseño detallado recuperado del método cStrl4::AlgoritmoDeInterfaz() 113 Figura 4.24 Diseño detallado recuperado del método cStrlS::AlgoritmoDeInterfaz() 114 Figura 4.25 Diseño detallado recuperado del método cStrl6::AlgoritmoDeInterfaz() 114 Figura 4.26 Diseño detallado recuperado del método SC-BASE:Produce() 115 Figura 4.27 Diseño detallado recuperah dP 10sNbf,dos CCC-VA::Crea(), J CCC-VB::Crea() 115 Figura 4.28 Diseño detallado recuperado de los métodos de la clase BASE 1I 6 Figura 4.29 Diseño detallado recuperado del método VAl::bdInicia() 117 Figura 4.30 Diseño detallado recuperado del método VAl::bdleea(unsigned int VAR) 117 Figura 4.31 Diseño detallado recuperado del método VAl::bdsca(unsigned int VAR) 118 vi INGENlERiA INVERSA DE CÓDiGO F U E ~ TEN E C+t PARA LA OBTENCION DE SU DISERO ÍNDICE DE TABLAS Tabla Página(s) Tabla 1.1 Herramientas que realizan ingenieria inversa de software para recuperar diseños 5.6 Tabla 2.1 Definición dirigida por la &axis para traducir expresiones de suma y resta en notación infija a notación posfija 21 Tabla 2.2 Esquema de traducción dirigido por la sintaxis que traduce expresiones aritméticas de suma y multiplicación, de notación en infijo a posfijo 30 Tabla 3.1 Muestras reconocidas por el analizador léxico de InverSOODA 61 Tabla 3.2 Esquema de traducción entre el lenzuaje C++ y diagramas de clases del UML 69-12 Tabla 4.1 Papel de los atributos y métodos del objeto Builder en el análisis semántico 9 1-94 Tabla 5.1 Deficiencias encontradas durante las pruebas a InverSOODA 121-122 vii \ - Capítulo 1 Conceptos Generales “EL RETO Siempre establece el camino, nimca sigas el sendero Anvli(nif ‘I i 1.1 1.2 i I I 1.3 1.4 1.5 1.6 1.7 1.8 Trabajos Relacionados Definición del Problema Objetivo de la Tesis Ilipótesis Bcneficios Esperados Límites y Alcances del Trabajo Metodología de Solución Referencias CAPiTULO TRABAJOS RELACIONADOS I : CONCEPTOS GENERALES En el ámbito actual de la Ingeniería de Software existen dos conceptos con íntima relación: la documentación de software existente y la recuperación de diseños 'de software. La importancia de la relación entre estos dos conceptos existe porque al recuperar el diseño de un software que ya existe, se cuenta con los planos con que se construyó. El diseño es una parte niedular de la documentación de un software, que se complenienta con otros elementos tales como los requisitos y las pruebas. La recuperación de diseños de software involucra la aplicación de ingeniería inversa. La ingeniería inversa de software es.un proceso que consiste en analizar código fuente para obtener uno o varios niveles de abstracción más elevados que'el propio código fuente. El diseño de un software, por ejemplo, es una abstracción más alta que el código fuente [preo21. La ingeniería inversa nomialmente se aplica desde herramientas especializadas que extraen información acerca de la arquitectura de un programa ya existente. Los tenias tratados en este capítulo tienen la intención de presentar los antecedentes y conceptos generales que preceden el presente trabajo. Todo gira en tomo a la recuperación de diseño por medio de ingeniería inversa; se mencionan los trabajos relacionados y la relación especial de las herramientas SOODA [PnrOO] e InverDDVi respecto a InverSOODA, la herramienta propuesta; se presenta el objetivo de este proyecto; se formula la hipótesis general . que sostiene la tesis; se exponen los beneficios, alcances y limitaciones; finalmente, se enumeran las actividades que comprende la metodología de solución propuesta. 1.1 Trabajos Relacionados Son varios los estudios que revisan métodos y técnicas de ingeniería inversa y también son varias las herramientas computacionales que aplican 'técnicas de ingeniería inversa con diversos fines. En esta sección se presentan algunos métodos y trabajos relacionados con la aplicación de la ingeniería inversa para recuperar diseños de programas. 1.1.1 Modelo de ingeniería inversa de Byrne' I r I Inlormacibn del diseno delaliado En el trabajo Eric J. Byrne se presenta un iiiodelo de ingenieria inversa que consiste en extraer información de diserio deiailado con abstracciones de alto nivel, desde código fiiente y documentos de diseño. Figura 1.1 Proceso básico de ingeniería inversa de Byme. I r ' Ciiado en [ WeiiOZ] 3 CAPiTULO 1: CONCEPTOS GENERALES Dicho modelo fue utilizado para recuperar el diseño de un sistema implementado en lenguaje Fortran, para implementar una nueva versión en el lenguaje Ada. El proceso básico que propone Byrne se resume en la Figura I . 1. 1.1.2 Modelo de recuperación de diseños de Biggerstaff Ted J. Biggerstaff [Big891 propone un modelo de recuperación de diseños aplicado al mantenimiento de programas y al enriquecimiento de bibliotecas para reuso. El modelo consta de tres etapas. Cada etapa provee los siguientes elementos respectivamente: 1) El entendimiento del programa para su mantenimiento. 2) El enriquecimiento de bibliotecas de reuso y recuperación. 3) La aplicación de los resultados de la recuperación de diseño. La Figura 1.2 ilustra el proceso básico de recuperación de diseños para programas escritos en C. Según Biggerstaff, este proceso se puede aplicar a lenguajes orientados a objetos con sólo una modesta variación'. El proceso básico comienza con un análisis que identifica estructuras . organizacionales a gran escala, tales como módulos, subsistemas y datos importantes. Enseguida se recuperan otras estructuras abstractas de diseño: diagramas informales, conceptos y relaciones informales, diseño racional, estructura de módulos y finalmente flujo de datos y de control. Durante este proceso se debe mantener el mapeo entre las abstracciones y los segmentos de código que las implementan. El Programa fuentcen c d Identificación de agrupaciones de módulos y datos abstractos Recuperación de i ) abstracciones de diseño i ) Mapeo de las abstracciones con el código I I1 Figura 1.2 Proceso básico de recuperación de diseños de Biggerstaff. Deigraciidumente no especifica que variación. El modelo no enloca su aplicación a sisl~niasorientados a objetos, pero sienta las bases de la recuperación de infamación de entidades con alta abstmcción - algo muy parecido u una clsse - y luego u la recupcración de los deialles de dichas entidades. 4 CAP~TULO 1: CONCEPTOS GENERALES TRABAJOSRELACIONADOS 1.1.3 Herramientas de ingeniería inversa Son numerosas las herramientas computacionales que realizan ingeniería inversa para recuperar diseños embebidos en código fuente. La diversidad de dominios, lenguajes y metas que comprenden estas herramientas hace imposible listarias todas. La Tabla 1.1 tiene la intención de mostrar al lector una síntesis de aquellas herramientas que tienen mayor relevancia para el presente trabajo. En cualquier caso, la columna denominada Contraste menciona los desventajas de las herramientas analizadas que no son tales en InverSOODA, la herramienta propuesta en este trabajo de tesis para recuperar diseños. Herramientas que realizan ingeniería inversa de software para recuperar disi os Dominio Descripción Relación Contraste IPADIC++ [ZavO2] Com.ponentes de Software. Una herramienta que utiliza un modelo can6nico de representaci6n de patrones de diseño. para rewnocer patrones de diseño en cddigo en C++. La identificaci6nautomática de patrones de disefio es un ejemplo de la recuperaci6n de una alta abstracci6n de disefio orientado a objetos. IPADIC++ no recupera los diagramas de clases que corresponden a los patrones de diseño. Tampoco recupera el diseno detallado de métodos de cIases. SOODA [ParOO] Modelado orientado a objetos. Permite diseñar diagramas de clases de UML y el disefio detallado de métodos de clases, apoyándosede DDVi. Es capaz de generar código en C++ a partir de los diagramas creados. Especial relación tiene esta herramienta en el presente trabajo: sobre la base de SOODA se propone InverSOODA, una nueva herramienta bldireccional. SOODA no recupera ni diagramas de clases ni diagramas de diseño detallado de métodos desde código fuente legado. LS/2000 [DeaOl] Software de tecnologías de informaci6n a gran escala con YK2, el problema de sistemas que no previeron el uso de fechas posteriores ai ano 2000. Es un software altamente automatizado oue El Y2K es un ejemplo tlpico en donde es común la aplicación de ingenieria inversa para la recuperación automatizada de disefios. Nombre - Aunque LS/~OOO trata directamente w n la recuperaci6n de abstracciones equivalentes al diseflo detallado, nc recupera precisamente el diserio detallado de funciones con algún tipo de diagramas. Tabla 1.1 Herramientas que realizan ingeniería inversa de software para recuperar diseños. i 5 C A P ~ U L1:OCONCEPTOS GENERALES - Herramientas que realizan ingeniería inversa de software para recuperar diseños (continuación ...) Nombre Dominio nverDDVi MBtodos Wen021 automatizadc de ingenieria inversa. IRT [DrtOZ] Aplicaciones gráficas interactivas. lational lose Jrofessional idition for :++ [Rat031 Desarrollo Model-Driven con UML. Descripción Es una herramienta de ingenieria inversa que permite visualizar el diseño detallado de un programa, utilizando la notación Wamier. Rqlación De especial relevancia es este trabajo, pues representa el módulo que recupera el diseño detallado de funciones de InverSOODA. Oesign Recovery Tool es una herramienta de exploración gráfica de apiicaciones en C/C++ muy peculiar; identifica explosiones de ejecución - la totalidad de los métodos llamados - que corresponden a las acciones ejecutadas por un usuario. Obtiene un mapeo explicito de las acciones de alto nivel -similares a iragmentos de escenarios de casosdeuso-wnsu. implementación de bajo nivel. , -~ . . Esta herramienta es una parte de Rational Suite, que es lider en el campo del desarrollo de software orientado a objetos y de componentes. Esta versión se puede integrar con MicrosoflVisual C++ para desarrollar software. El mapeo de ejecuciones de métodos con escenarios de casosdeusose puede usar para recuperar diseños j documentar las funciones más usadas de manera gráfica. Rational Rose es Ií herramienta propuesta por el Object Management Group para promover y usar el UML. Realiza ingenieria inversa directa de código para Visual C++ entre otros lenguajes de programación. ,Contrasfe La principal desventaja frente a InverSOODA es que. por sí sola, sólo funciona para sistemas escritos en lenguaje C. Su enfoque no contempla la recuperación de abstracciones equivalentes a cIases. DRT es una herramienta experimental que deja de lado la recuperación de la vista estática envestida en los diagrama de clases. Tampoco se puede decir que es exactamente la recuperación del diseño detallado de métodos su finalidad. En cuanto a ingenieria inversa, Rational Rose enfoca sus esfuerzos a la recuperaci6n de diversas abstracciones de diseño, entre otras, el diagrama de clases, pero no hace recuperación explicita del diseño detallado de los mbtodos de clases que aparecen en dicho diagrama de clases. Tabla 1.1 Herramientas que realizan ingeniería inversa de software para recuperar diseños. (continuación...) 6 1 CAPiTULO 1: CONCEPTOS GENERALES DEFINICIÓNDEL PROBLEMA 1.2 Definición del Problema De acuerdo con Chikofsb 'ch'wl, "Las fases de ciclos de vida evolutivos involucran la transición de altos niveles de abstracción en etapas tempranas, a bajos niveles de abstracción en etapas posteriores". Además, comenta que en dichas etapas: "...la ingenieria inversa cubre un amplio rango de etapas que comienza con la implementación existente, la recuperación o recreación del diseño y el descifrado de los requerimientos que de hecho se implementan en el sistema...". De aquí se desprende que en los modelos de ciclos de vida3, la aplicación de ingeniería inversa se da en varias etapas y puede considerar tanto las abstracciones de alto nivel como las abstracciones de bajo nivel. ,, En el contexto de desarrollo de sistemas orientados a objetos, independientemente del modelo de ciclo de vida, el diagrama de clases se encuentra .en un nivel de abstracción mayor que cualquier diagrama de diseño detallado. Ninguno es más importante, mas bien son complementarios. Existe 'en la actualidad una diversidad de herramientas que recuperan diagramas de clases y, sin embargo, dichas herramientas parecen haber dejado .en el olvido la recuperación del diseño detallado de los métodos de clases. Esto impide realizar ingeniería inversa de una importante abstracción de bajo nivel, como lo es el.diseño detallado. # El problema se extiende de alguna manera a la herramienta SOODA, pues, por principio de cuentas, no es una herramienta bidireccional; no puede hacer ingeniería inversa a partir de código fuente en C++. El problema que res$elve este proyecto de tesis es precisamente el de construir una herramienta basada en SOODA, que sea bidireccional al permitir la recuperación del diagrama de clases del UML y el diseño detallado de métodos de clases con diagramas de Wamier.:Al final, se tendrá como producto el software denominado InverSOODA, la herramienta bidireccional. 1.3 Objetivo de la Tesis 1 El objetivo de esta tesis es generar un mecanismo de ingeniería inversa para recuperar el diseño de clases y el diseño detallado de métodos de clases desde código que ya existe escrito en C++. 1.4 Hipótesis I En este trabajo se plantea como hipótesis que es posible generar el diagrama de clases basado en el estándar UML y los diagramas de Warnier para representar el diseño detallado de métodos de clases, a partir de código fuente existente en C++. ' L l h e s c el tradioional modela en cascada. el c v o l ~ t i v omodelo en espiral. etc. 7 CAPhULO 1: CONCEFTOS GENERALES 1.5 Beneficios Esperados Se contará con InverSOODA, una herramienta de ingeniería de software que realiza ingeniería directa e ingeniena inversa de programas en C++. La ingeniería directa provee los mismos beneficios que la herramienta SOODA. A su vez, la ingeniería inversa obtiene diagramas con el diseño de clases y el diseño detallado de los métodos de clases, desde código fuente existente. Los diagramas recuperados representan un modelo estático y dinámico que son parte de la documentación del diseño del código fuente. La recuperación del diseño detallado de métodos representará un valor agregado respecto a las herramientas para análisis y diseño orientado a objetos en el mercado, pues a la fecha del inicio de este trabajo ninguna ataca el problema. El diseño arquitectónico de InverSOODA se reorganizó con patrones de diseño orientados a objetos a partir del diseño original de SOODA. Esto facilitará las extensiones y modificaciones a posteriori a la arquitectura de la herramienta. 1.6 Límites y Alcances del Trabajo El analizador sintáctico de C++ construido .para la herramienta InverSOODA reconoce un subconjunto de la gramática de C H 4 , lo que repercute en que no se identifican directivas de preprocesamiento ni se recuperan templates de Ctt. InverSOODA no verifica errores en el código fuente sujeto a análisis. Por lo tanto, éste no debe tener errores de compilación ni de ejecución. De lo contrario, se obtendrán mensajes de error. Además, el código fuente debe estar organizado con su definición de clases dentro de un solo archivo con extensión h ó hpp y la implementación de los métodos de clases dentro de archivos independientes con extensión c Ó cpp. Si bien existe la posibilidad de usar notaciones de diseño detallado más divulgadas que la de Warnie?, InverSOODA echa mano del conocimiento adquirido con InverDDVi para resolver la diagramación del diseño detallado de los métodos de clases. InverSOODA utiliza todo elemento gráfico de SOODA para la ingeniería directa. Sin embargo, el mecanismo de ingeniería inversa sólo recupera relaciones de herencia y de agregación entre clases, pues el analizador sintáctico no reconoce apuntadores y por ende relaciones simples o de dependencia entre clases. 1.7 Metodología de Solución La metodología empleada en la construcción de InverSOODA involucra las siguientes actividades: ' El Anexo A de este documento contiene dicha gramática. ' Los tradicionales diagramas de flujo por ejemplo. 8 e<.. ! . * ,"U. ' I :C%L$?"SrA.+l.." .. t ~. .i .'I, CAPITULO 1: CONCEPTOS GENE~ALES METODOLOG~A DE SOLUCIÓN 1. Revisión de la arquitectura de clases y funcionamiento de SOODA. Para efectos de agregar a la arquitectura de SOODA la capacidad de realizar ingeniería inversa, se realizó una revisión exhaustiva de su diseño de clases y una modificación de aspectos de diseño puntuales para lograrlo. I . A partir de esta las siguientes preguntas encontraron respuesta: ¿qué estructura de datos se,usan y cómo se manipulan?, ¿Cómo se manejan los eventos de interfaz e usuario?, ¿Cómo están organizadas sus clases?, ¿Qué clases se pueden extender o agregar para poder hacer ingeniería inversa? . r revision, 2. Reorganización de aspectos de diseño orientado a objetos puntuales con patrones de diseño. La idea original fue utilizar el patrón de diseño Builder [Gam951 para proveer un diseño reusable que permitiera construir un objeto'diagrama a partir de la información que arrojase el analizador sintáctico. Pero, conforme se fue detectando la posibilidad y conveniencia de aplicar otros patrones de diseño que colaboraran con el Builder, entonces se reorganizó gran parte del diseño de clases de la arquitectura original de SOODA. ., Se estudiaron la d a or parte de'los patrones de diseño que tienen relación con el patrón Composite 'l. En SOODA, ya se utilizaban algunas bondades de la programación orientada a objetos con el uso de una clase abstracta denominada Figura; objetos concretos Figura se guardaban genéricamente en una lista de punteros a.objetos del mismo tipo: Figura. Sin embargo, no se podía hablar del patrón Composite inmerso en su arquitectura. Dos objetos Builder concretos,'uno para la ingeniería directa y otro para la ingeniería inversa, construirían una estructura Composite para cada diagrama de clases generado por InverSOODA. J 3. Estudio de formalismos que sustenten el análisis sintáctico. La recuperación de cualquier tipo de información desde código fuente tiene dos principales alternativas: la constnicción de analizadores manuale's o.el uso de formalismos como la teoría de autómatas y be compiladores. La finalidad de esta actividad fue encontrar un esquema de traducción formal entre lenguajes basándose en acciones semánticas. La definición dirigida por la sintuxis fue el objeto de estudio que se acoplaba más para el propósito de InverSOODA. 4. Estudio y selección de diferentes herramientas que generan analizadores sinthcticos de manera automática. La herramienta ANTLR-2.7.1 fue la elegida entre varios productos, para generar automáticamente el analizador léxico y sintáctico que analizaría el código fuente legado. Además de manejar notación gramatical EBNF, la gran ventaja que guió esta decisión, es que ANTLR es un marco.de trabajo orientado a objetos que permite crear objetos h e r y parser en el lenguaje C t t . Entonces se creó una librería estática que provee la . , 9 CAPiTULO 1: CONCEFTOS GENERALES funcionalidad de análisis léxico, sintáctico y semántico necesarias (además de poder agregar objetos Builder) para recuperar los diseños en cuestión. Las acciones semánticas del analizador sintáctico generado con ANTLR son las que propiamente realizan la ingeniería inversa. Consiruyen con un objeto Builder el diagrama de clases a partir de la información que arroja el análisis sintáctico. 5. Identificación del subconjunto de la gramática de C++. Se identificó una subgramática para C++ escrita en notación EBNF que alimenta al ANTLR. Este subconjunto gramatical de C++ es el suficiente para reconocer y descubrir nombres, atributos, métodos de clases y relaciones entre clases. Se revisaron la literatura especializada y algunos los archivos con definiciones de gramáticas para C ya existentes. 6. Implementación del rediseño para InverSOODA e implementación de las acciones semánticas del analizador sin fáctico. La codificación e integración del analizador sintáctico a la nueva arquitectura fue el paso lógico a seguir, habiendo analizado y diseñado los aspectos mencionados en los pasos anteriores de este subtema. 7. Realización de pruebas y reflexión sobre resultados obtenidos. Si bien se realizaron pruebas y ensayos empíricos no documentados durante las diferentes etapas del desarrollo de InverSOODA, también se definieron dos casos de prueba específicos que verificarían y demostrarían la eficacia de la herramienta6. 8. Escritura de la memoria de tesis A partir de los resultados obtenidos durante el desarrollo de la herramienta y aplicación de casos de prueba, se escribió el presente documento que sustenta la tesis. La Figura 1.3 en la página siguiente, resume las actividades que corresponden a la metodología descritas en la enumeración anterior. 1.8 Referencias [Big891 Biggenlaff. Ted J. Design Recovery for Mainienance end Reuse Computer. (E.U.: IEEE Computer, Julio de 1989) pp. 36-49. [Chi901 Chikofsky, Elliot J. [y] Cross 11, James H. Reverse Engineedng and Design Recovery: A Taxonomy. (E.U.: IEEE Somare. Enem de 1990) pp. 13-17. Revise el Capitulo 5. 10 REFERENCIAS CAP~TULOI : CONCEPT~SG E N ~ M L E ~ [DeaOl] Dean, Thomas R. Et al. Using Design Recovery Techniques to Transform Legacy Systems. (Canada: ICSM 2001 IEEE International Conference on Software Maintenance. Florence, Noviembre de 2001). [Ort02] DRT. Design Recovery Tool. httD:llwww.cse.unsw.edu.aul-driíindex.hlml14 de Enero de 2003. [Gam951 Gamma Erich et al. Design Pafferns-Elemenls of Reusable Object-Oriented Sohare. (E.U.: AddisonWesley-Longrnan.1995)pp. 97-106. 163-173. [ParOO] Parta Ramirez. Isaac A. Modelado Visual Orientado a Objetos. (Tesis de Maestria. CENIDET, Cuernavaca. Morelos, México. Diciembre del 2000). [PreO2] Pressman, Roger S.Ingeniería del Soflwara. Un enfoque pdctico. Quinta Ed. (Madrid, Espaíia: McGrawhillllnteramencanade España. 2002) p. 546. [Rat031 Rational Software Corp. httD:llwww.rational.comlDroduclslroselclcc.isD 14 de Enero de 2003. [Wen021 Wences Diaz. Martha F. Modelo de ingeniería inversa para la obienci6n de diseno detallado basado en LEVISS. (Tesis de Maestria, CENIDET. Cuernavaca, Morelos, México. Febrero de 2002) pp. 15. 28-39. [ZavOZ] ,,Zavalela Carrillo. Patricia. Reconocimiento de Patrones de Diseño de Gamma a partir de ia fonna candnica definida en el IPADIC++. (Tesis de Maestria. CENIDET. Cuernavaca. Morelos..MBxico, Enero de 2002). Figura 1.3 Diagrama de actividades de U M L de la metodología de solución empleada. 11 I 03- O 3 3 4 Capítulo 2 “Elcamino sigueysigue ...” B. Baggins 2.1 2.2 2.3 2.4 2.5 2.6 2.1 2.8 Antecedentes Definiciones de El Lenguaje Unificado be Modelado Diseño Detallado en InjerDDVi Base Teórica del Análisis de Código Construcción Automátiya de Analizadores Sintácticos Patrones de Diseño Orientados a Objetos Referencias I CAPÍNLO 2: MARCO TEóRiCO ANTECEDENTES . . . 2.1 Antecedentes 2.1.1 Ingeniería inversa e ingeniería inversa de código IMOIOO] al entendimiento de software: la ingeniería inversa Para el entendimiento de software industrial o resuelve la incógnita sobre qué información se en contextos diferentes. El famoso problema del año dos mil y la migración de sistemas de información hacia aplicaciones Web o hacia elcomercio electrónico, entre odos, han propiciado el interés por crear conceptos y técnicas para la ingeniería'inversa de datis. El incremento del uso de bodegas de datos y técnicas de minería de datos también han {ido motivo de interés, concretamente para la ingeniería inversa de bases de datos. Hoy día, existen dos "En sistemas con pobre e' es la única fuente confiablede . información acerca del sistema. " I No ohstante, el esfuerzo de investigación para la ingeniería inversa dd datos no ha tenido una significativa representación en la Ingeniería' de Software. Aparentemente, la ingeniería inversa de I un reto más desafiante, además de que ha existido código representa una tradicional división entre ingenieros de software y desarrolladores de sistemas .de bases de datos. Müller et al comentan: "Durante la evolución del software, se aplican C 'mbios al código fuente para añadirle funcionalidad, corregir sus defectos y mejorar su calidad. En sistemas con pobre HausiA. Mü"er documentdpión, el código es la única fuente confiable de información acerca del sistema. Como resultado, el proceso de ingeniería inversa se ha concentrado en entender el código". 7 ' Mejor conocidos como Sirlemas de Infamación. 15 CAPiTULO 2: MARCO TE6RICO Estos comentarios dejan ver, de alguna manera, por qué es relevante el entendimiento de código fuente. Sin embargo, falta precisar algunos de los frutos o beneficios concretos que proveen las capacidades de ingeniería inversa de código. Dichos beneficios incluyen la descomposición en subsistemas; análisis de conceptos; identificación de diseños, programas y patrones de cambio; slicing de programas; análisis de dependencias estáticas y dinámicas; métricas orientadas a objetos; exploración y visualización de software. Se habla entonces de artefactos de sofwure al referimos a una abstracción de determinado nivel que se encuentra embebida dentro del código fuente, y que puede ser recuperada por mecanismos de ingeniería inversa. Müller et al también nos indican que existe una importancia en la continuidad en el entendimiento de programas: “Para evitar una crisis, es importante tratar las necesidades de información más efectiva durante el ciclo de vida un software. Se necesita dar soporte al seguimiento de los artefactos de software’’. Por ejemplo, en la ingeniería directa es importante obtener los elementos de código que lo implementan. En la ingeniería inversa, dado un archivo u objeto fuente, se debe tener la capacidad de obtener la política o responsabilidad que implementa. De igual forma, es importante determinar cuando es más apropiado enfocar el análisis en diferentes niveles de abstracción. La Figura 2.1 ilustra las tendencias actuales de la ingeniería inversa además de resumir los elementos analizados y los beneficios obtenidos. S e aplica a (en): Bodegas de datos; Ingeniería Inversa rla nntm Mineria de dalos; y, Bases de dalos relacionales Ingeniería Se obtiene(n): Objetos centrales de negocios para migrar sislemas a plataformas onentadas a obJetos: Map- entre e ~ t ~ c h l r ades datos legadas y un modelo de objetos mmún para negocios o infraestmclums moperalivas Web: y. Aseguramiento de wlidad integral de sistemas de samate que usan eslniclurasde datos persistenles o esquemas mn sistemas maneladores de bases dedalos. I””T)C%? ingenieria Inversa de Ceidigo I1 rI Se obtiene(n): Descamposici6n en subsistemas; Sintesis de conceptos: Identificaci6n de diseno y patrones de cambio; Rebanado de programas: AnBlisis de dependencias estdticas y 1 Se aplica a: CddiQo fuente dinhmicas; MBtrica~orientadas a objetos: y. Explaraci6n y.visualiraci6n de somare. Figura 2.1 Áreas de aplicación actuales de la Ingeniería Inversa de Software. 16 r CAPITULO 2: MARCO TEÓNCO ANTECEDENTES El grupo de Ingeniería de S o h a r e del CENIDET ha estado desarrollando a la fecha, un ambiente de desarrollo de s o d a r e orientado a objetos denominado Suite CENIDET-UML. El proyecto involucra como pahe medular al Lenguaje de Unificado de Modelado (UML). Mediante el uso del UML se p!etende auxiliar el desarrollo de software evolutivo orientado a objetos, modelando las siguikntes vistas: vistas .estáticas de clases y paquetes, casos de uso y vistas dinámicas de estadbs, secuencias y actividades. Además, se tiene planeado dar un valor agregado a la suite queI normalmente las herramientas comerciales no presentan: el modelado del diseño detallado Ide los métodos de clases más la documentación y pruebas asociadas al sistema. a Entre los módulos que contendrá la suite se tienen los siguientes*: I a) SOODA*, modela diagr , mas de clases del UML y diagramas de Wamier para el diseño detallado de métodos, apoyándose de DDVi para los segundos. Genera código fuente en C+ a p h i r del modelado de diagramas de clases. b) InverDDVi*, modela dibeño detallado con diagramas de Wamier. Auxilia a SOODA para generar el c)ódigo fuente de métodos de clases en lenguaje C++. c) SIDDO*, detallado de métodos de clases utilizando Tiene embebido un analizador diagramas sea válida en función de sintáctico' que una gramática visual para de actividades. medio de diagramas de casos de uso d) Un módulo que modelará los documentos de requerimientos y del UML. Con esta pruebas del sistema. e) Un módulo que permitirá btener de forma automática los diagramas de secuencia del UML, tomando infodación de 1os.diagramas de clases y de diseño detallado generados con SOODA. d d e m h , permitirá el cálculo.automático de la métrica de acoplamiento para sistemad,orientados a objetos: f) Un módulo que mode ará el comportamiento ,dinámico de los objetos correspondientes a las clases modeladas con SOODA, por medio de los diagramas P \ de estado del UML. I g) Un módulo que presentará la vista de paquetes correspondientes a grupos de clases con responsabilidad común)I gmpos que serán modelados previamente con SOODA. Durante el desarrollo de la Suite CENIDET-UML ya se han obtenido resultados Sin embargo, el prototipo original de SOODA concretos y satisfactorios en cierta apoya la fase de diseño de clases y la no está completo. El estado generación del código en C + + que las implementa, en complicidad con InverDDVi. En otras palabras, hace ingeniería dir&a. No obstante, hace falta dar soporte al seguimiento de código generado. La suite presudone el apoyo al desarrollo de sofhvare evolutivo y esto recuperar y entender algún artefacto de software implica que en algún momento se producto de la ingeniena directa. 'Los módulos señalados con I asterisco uten terminados y los dcmb sc ~n~ucnlran cn desarrollo a la fecha I CAPfTULQ 2: MARCO TEÓRICO Concretamente, se pretende que SOBDA sea un módulo bidireccional que sea capaz de recuperar diseños desde código fuente3. Con InverSOODA, el nuevo prototipo de SOODA propuesto en este trabajo, se cuenta ahora con la capacidad de recuperación a partir del código fuente escrito en C++ de al menos dos niveles de abstracción de diseño: el diagrama de clases y el diseño detallado de métodos. Con dicha capacidad es factible el entendimiento y la reestructuración potencial de las tempranas decisiones de diseño arquitectura]. Es importante notar que InverSOODA se puede catalogar como un software que realiza ingeniería inversa de código para identificar diseño, de acuerdo con la Figura 2.1 de la sección 2.1.1. 2.2 Definiciones de Conceptos Centrales En esta sección se definen los conceptos que tienen que ver directamente con el tópico central del presente trabajo: la ingeniería inversa de software para recuperar diseños. La definición puede o no venir acompañada de un comentario o nota crítica que vincula el concepto definido con el menester del proyecto o con alguna otra sección del documento en específico. 2.2.1 Ingeniería inversa Chikofski [Chigo] nos da la siguiente definición en su Útil taxonomía: “La lngenieria Inversa es el proceso d e analizar un sistema sujeto a estudio para: a) identificar los componentes del sistema y sus interrelaciones; y, b) crear representaciones del sistema con otra forma o con un mayor nivel de abstracción.” Por su parte, Pressman [preo21 asienta que ia ingeniería inversa es: ”... el proceso que consiste en analizar un programa con uno o vanos niveles de abstracción más elevados que el código fuente. Generalmente se aplica desde herramientas de reingeniería que extraen información acerca d e los datos, arquitectura y disefio de procedimientos de un programa ya existente.” AI revisar estas dos definiciones se encuentran similitudes: ambas hablan de un “proceso que analiza s o h a r e para identificar o extraer abstracciones de mayor nivel”; aunque la definición de Pressman sí introduce el elemento herramienta, ¿quizá por ser un texto más actualizado?. De cualquier manera, esta cuestión no interesa a la hipótesis planteada en la tesis y se invita al lector a repasar la sección 2.1 para que deduzca sus propias conjeturas4. ’Explicitamentecn [ParOO] se menciona la necesidad a postcnori de agrcgar la Capacidad de ingenieria inversa a SOODA. Además. para ver ejemplos concretos de procesos a los que se refiere la definici6n de ingenicna invcna repasc las secciones 1:l.i y 1.1.2 deestedocumento. 18 .CAP~NLO 2: MARCO TEÓRICO DEFINICIONES DE CONCEPTOS CENTRALES 2.2.2 Ingeniería directa 2.2.3 Reestructuración 1 semántica)" [Chi901 2.2.4 Redocumentación Chikofsky nos dice que la rkdocumentación es la más antigua y simple forma de la ingeniería inversa, y que se .codsidera también una forma de reestructura de código no intrusiva. El prefijo re es recuperar <ladocumentación del sistema también indica volver a hacer la ingeniería del que existió o que debió sistema pan' mejorarlo. algunos ejemplos de herramientas que realizan redocumentación: - Pretty-printers. El es un anglicismo para denominar el despliegue de listados de código de una manera mejorada. Generadores de diagrama?. Herramientas que crean diagramas directamente del código para reflejar el control o la estructura del mismo. Generadores de cruzada. La meta de estas herramientas es para visualizar relaciones entre los elementos que proveer maneras más componen programas. 2.2.5 Recuperación de diseños 1 I "La recuperación de disenos es un hbconjunto de la ingenieria inversa en donde se agrega información externa, conocimientos de dominio, y deducciones o razonamiento difuso al entendimiento d e u n sistema de software, para identificar abstracciones de alto[Chi901 nivel más . significativas que aquellas obtenidas dk examinar directamente el sistema por si solo" I CAPITULO 2: MARCO TE~RICO ~ Chikofsky cita a BiggerstaffS parañmblib las ideas expresadas en su definición: ’...La recuperación de diseilos recrea abstracciones de diseño desde una combinación de código. documentación existente (si existe),experiencia personal y conocimiento en general acerca de un problema y dominios de aplicación... La recuperación.de diseños debe reproducir toda la información requerida por una persona para entender plenamente lo que hace un programa, cómo ío hace, porqué lo hace, etc. Por lo tanto, lidia con un rango mucho mayor de información que el que se obtiene en las representaciones o código convencionales de la ingeniería de software” Byrne6 nos proporciona otra definición: “El proceso de reconstruir el diseño de u n programa es llamado recuperación del disefio y es un elemento del proceso de ingeniería inversa”. Sin profundizar por el momento en las diferencias entre la definición de Chikofsky y Byrne, cabe hacer notar la diferencia entre recuperación de diseños y redocumentación en cuanto a alcance de enfendimiento de soffware, según las definiciones de esta sección y de la sección 2.3.3 respectivamente. De acuerdo a las ideas de Biggerstaff, la recuperación de diseños se antoja como un proceso mucho más completo y ambicioso que la En redocumentación, quizá porque dan énfasis al mantenimiento y reuso de s o f i a r e cualquier caso, a la hipótesis que sostiene el presente trabajo no compete comprobar que la recuperación de diseños debe obtener altos niveles de entendimiento de software, al estilo Biggerstaff, mas sí lo es obtener dos niveles de abstracción de disefio diferentes para software en C++. 2.2.6 Mantenimiento de software “La definición ANSI de mantenimiento de software es la modificación de un producto de software después de su entrega para corregir fallas, para mejorar el desempeño d e otros atributos o ara adaptar el producto en un ambiente modificado, de acuerdo al ANSlllEEE Std 729-1983.” [ChiOfi El mantenimiento de software es un contexto en donde la ingenieria ihversa tiene cabida. De hecho, los términos ingeniería inversa y reestructura de s o f i a r e caen dentro la definición global del mantenimiento de software. Se habla de quien aplica mantenimiento a un sistema como alguien que potencialmente se apoya de herramientas de ingeniería inversa, cuando examina y entiende cierto sistema de software. Ciertamente, no es utópico pensar que el módulo InverSOODA se vea, en potencia, involucrado a futuro en cuestiones de mantenimiento de software, si en ese momento se encuentra apoyando el desarrollo de software evolutivo. ’ La sección 1.1.2 de este documento presenta un resumen de los elementos Biggerstaff. 6 .. básicos del modelo de recuperación de disefios pmpucslo por La iección I . I .I de este documento presenta un resumen de los elementos básicos del modelo de’ingenieda invens de Byme. 20 . ~ CAPITULO2: M k C O TE~RICO 2.2.7 . , DEFINICIONES DE CONCEPTOS CENTRALES Reingeniería "La reingenieria, también conocid( como renovación y reclamación, es la examinación y alteración de un sistema ara reconstituirlo en una nueva forma y la subsiguiente implementación d e la nueva forma" [CiP,Ol 2.2.8 Software legado legado: 1) "Son programas que son criticos' para la operaci6n de las compañías, pero que fueron, El Lenguaje Unificado de Modelado (UML por sus siglas en inglés) es en esencia un conjunto de diagramas que compkndian los métodos de modelado de Booch, Rumbaugh, y Jacobson. Originalmente, el UMd representó un lenguaje visual que nació de la necesidad de generar diseños sólidos que tanto clientes, analistas y desarrolladores aceptaran como pauta para modelar sistemas de sdftware de negocios. Hoy día, se enfoca a ser un lenguaje de modelado estándar para desdollar las fases de análisis y diseño de aplicaciones de sistemas orientados a objetos [RumOi]1 . El UML provee básicamente odos los esquemas, vistas o perspectivas que permiten de sus diagramas. Los diagramas más importantes entender el diseño de un sistema a son: el diagrama de clases, el de secuencias, el diagrama de casos de uso, el diagrama de actividades, entre otkos, Todos ,estos se elaboran según las necesidades del sistema y la etapa de desarrollo ed que se encuentre el mismo. Este lenguaje se distribuye de manera pública y gratuita en vakos documentos ue resentan los conceptos básicos del modelado: su significado y su representación gráfica%*&I . I Hoy día, el Lenguaje Unificado de Modelado está siendo incorporado en la mayoría de las herramientas de software comerciales que modelan sistemas orientados a objetos, además de ser constante objeto de estudio. por parte de las instituciones de investigación [LOP021 21 I SEP CENIDET CENTRO DE, INFORMACION C A P ~ L2:OMARCO TEÓRICO . 2.3.1 El modelo estático de clases - . .. .. .. . El diagrama de clases del UML provee la vista estática de un software orientado a objetos: "... en un principio llamados modelos de objetos, muestran las clases del sistema y sus interrelaciones (incluidas la herencia, agregación y asociaciones)" [Amb981. Además, de manera opcional pueden mostrar los atributos y/o .los métodos de las clases: "... los métodos se documentan con una descripción de su lógica y los atributos se documentan con una descripción sobre qué contienen. su tipo y una indicación d e rango de valores. Las relaciones entre[Amb98] clases se documentan con una descripción de su propósito y una indicación de su cardinalidad..." La siguiente cita de Scott W. Ambler [Amb981, enriquece las descripciones del párrafo anterior: "La información contenida en un diagrama de clases se mapea directamente con el código fuente que será escrito para implementar la aplicación y por ende un diagrama de clases siempre debe ser dibujado para una aplicación orientada a objetos." Con InverSOODA se puede realizar ingeniería directa para crear un diagrama de clases y generar el código en C++ asociado al diagrama. En el renglón de recuperación de diseños hace propiamente lo inverso: es capaz de recuperar el diagrama de clases a partir del código que generó. 2.3.2 EL modelado dinámico con el UML Tradicionaltmente el modelado dinámico de software con el UML.se entiende como el modelado de estado y comportamiento de objetos. Los diagramas de estados del UML se usan para modelar precisamente el estado y comportamiento de objetos, puesto que en dichos diagramas se pueden representar las transiciones o cambios de estado durante la vida de un objeto. En otras ralabras, "Los diagramas de estados muestran los detalles dinámicos de las operaciones" [Sch O] Por otro lado, tanto los diagramas de distribución como los diagramas de actividades del UML normalmente también se consideran como diagramas con enfoque dinámico. Los diagramas de distribución presentan la configuración en tiem o de ejecución de componentes de hardware y el software que se ejecuta sobre éstos Ihb9 8pl. Por su parte; los diagramas de actividad se usan "... para documentar la lógica de un solo método.de operación o el flujo de la lógica d e un proceso de negocio"[Amb981 "El diagrama de actividades es una extensión del diagrama de estado. Los diagramas de eitados destacan los estados y representan actividades como flechas.Los d e actividad se enfocan en las actividades." [School Actualmente, InverSOODA no basa el modelado dinámico de sistemas por medio de los diagramas del UML descritos en esta sección. La idea es aprovechar el conocimiento adquirido con InverDDVi para representar detalles dinámicos o flujo de la lógica procedimental de los métodos de clases. Como se indica en la sección 2.1.2, los módulos c) y f) de la Suite CENIDET-UML representan la parte que se planeó para cubrir apropiadamente el modelado dinámico de sistemas con diagramas del UML. : I '<'.- .' 22 CAPhULO 2: MARCO TEÓRICO perspectiva de diseño propia de debe olvidar que para DISEÑODETALLAWEN INVERDDVI de diseño detallado proporcionan una del paradigma por procedimientos, pero no se secuenciales, decir entonces que, para fines prácticos como vehículo para inspeccionar en C++. Se recomienda la representación de control [loy90]. 23 CAPINLO 2: MARCO TE6RICO ¿Queda explicita en el UML la representaci6n de diseño detallado orientado a objetos? Una anécdoia Durante el curso intitulado Tecnologia software para ambientes Web", impariido en Enero del año 2000 dentro de las instalaciones del CENIDET. al Dr. Oscar Pastor López (Jefe del Depto. de Sistemas Informátiws y Computación de la Universidad Poiitécnica de Valencia), se le hicieron. entre otras, preguntas con alusión a la siguiente idea: ¿Queda explicita en el UML la representaci6n de diseño detallado?. El wntexto en ese momento era la exposición de la intención de los diferentes diagramas del es6ndar UML. Recreando s610 la esencia de las preguntas. sin tomar las palabras corno se dijeron literalmente: Asistente al curso: Doctor, ~ c 6 m ose puede utilizar una notacidn detallada w n UML? Dr:: ... 'En verdad os digo que has puesto el dedo en la llaga. Recuerde que el UML es una especificación lodavia incompleta" Asistente al curso: ¿Ud. cree que el estado actual del UML permite modelar disefio detallado de métodos de dases. con alguno de sus diagramas?. Tomándose algunos segundos, volteando hacia arriba y finalmente apresurándose a contestar: 'El uso de diagramas del UML para eso mmhh. es cuestionable..." La anterior a n h i o t a no tiene otro fin más que el de recalcar que hasta ahora no existe en el estándar una convenclón acerca de qué diagrama es el más apropiado para modelar ei disefio detallado. La validez del uso de un diagrama u otro es válida en términos del wntexto de desarrollo y utilidad que al desarrollador le provea. ¿Alguna vez habr6 escuchado el lector la frase Estoy programando C++ estnicturado?. O bien la persona que dedar6 eso ignora la evoluci6n de los.paradigmas de programaci6n. o bien [intenta decir que le es práctiw.mezclar código en C wn objetos o viceversa!. Lo anterior no es tan .descabellado si se hace. por ejemplo, un reuso de funciones de la biblioteca estándar de C dentro de objetos. lo cual finalmente puede ser una estrategia útil para usar.funciones estándar probadas a manera de un wrapper0 un adapter: is #include isldio.h, class BufferedCutputScream I public: : public OulpuLStr~ani virtual inr YriLelFlLE 'ptr. I I char 'buffer1 retvm furite,b"ffer. 1. buffelre. PtTii //.rapper i f e l d e d s c66igo ... 1 Lo cierio es que la lecnologia de'modelado del UML presupone una orientación a objetos pura y no contempla la inclusión de elementos. procedurales. En el wntexto del desarrollo de InverSOODA se identific6 un nicho de oportunidad al enwntrar que la ingeniería inversa del disefio detallado de métodos es, para fines prácticos. un mecanismo iitil vara recrear el disefio detallado de un lenouaie concebido híbndo desde su diseño. como lo es C++. 2.5.1 Niveles en los que se puede aplicar el análisis de código J. Howard Johnson sugiere un listado general de los niveles en que se puede aplicar el análisis de código para obtener entendimiento de código: I . Texto simple: El cuerpo del código se considera como una colección de archivos cada uno de los cuales es una secuencia de caracteres agrupados en líneas. 24 *> _I CAPhuLO 2: MARCO TEÓRICO BASE TEÓNCA DEL ANÁLISISDE CÓDIGO 2. Texto preprocesado: En lenguajes con preprocesadores de nivel textual como C O PLfI, el efecto de aplicar el preprocesador a .la colección de archivos es la expansión de macros e inclusiones. El resultado de dicha expansión es que el contenido de archivds individuales será entonces compilable, pero entonces se habrá perdido una sbpificativa 'cantidad de estructuras tales como constantes, funciones en línea, entre otros. ~a estructura. organizacional reflejará entonces cÓ y el cargador analizarán y constxuirán la aplicación. 3. Secuencia de Lexem léxico de un compilador se habrá aplicado a los archivbs individuales y reemplazado el contenido de éstos con una secuencia de elerdentos léxicos llamados lexemas. 4. Árbol Sintáctico: secuencia de elementos sintácticos se analiza con un parser que interpreta dentro de cada archivo un módulo analizador sintáctico válido y prohuce un árbol sintáctico. I . 5 . Arbol Sintáctico con anotaciones y Tabla de Símbolos: El árbol sintáctico se ha transformado para quitar la información sintáctica que no afecta .el significado. Las declaraciones de variables en el código ahora son entradas en una tabla de símbolos qua identificb propiedades de entidades semánticas. Las ocurrencias de las entidades en el ákbol sintáctico se correlacionan con la tabla de símbolos. estudian flujos de control y datos particulares de la llegar a un entendimiento de lo que hace el código. 6. Ejecución Abstracta: lógica del programa, Los niveles sugeridos por Jobson son muy parecidos a las fases de análisis de un. compilador. La explicac.ión es qud existen formalismos comunes a los formalismos en los ,que se basa un compilador, como be muestra en la siguiente sección. La diferencia entre ambos formalismos es de intenciód. Un compilador no se enfocan hacia la traducción entre código ejecutable. lenguajes, más bien'a la 2.5.2 Traducción De manera análoga de contexto (LLC), se puede traducción de un lenguaje comúnmente como traductores. libres .de contexto de contexto (GLC) genera un lenguaje libre un mecanismo basado en GLC que genere la 'B'. Estos mecanismos son conocidos I tomados de [San981 25 CAP~TULO 2: MARCO TE~RICO El esquema de traducción dirigida por la sintaxis es el tema sobre traducción de lenguajes que se trata en ambas partes con cierta similitud y que se aborda con mayor profundidad en esta sección. 2.5.2.1 Traductores ISan981 Un traductor es un dispositivo tal que, dada una cadena de entrada x , calcula una cadena de salida y, de manera que el par ordenado (x, y) está en una traducción T dada. La traducción debe tener las siguientes características: a) Debe ser legible. Esto es, debe ser fácil determinar cuáles pares (x, y) existen en la traducción. b) Debe ser posible construir mecánicamente un traductor eficiente, para que la traducción se efectúe de manera directa desde la definición de ésta. Características deseables en traductores: u Operación eficiente. Para una cadena de entrada w de longitud n, la cantidad de tiempo requerido para hacer un análisis sintáctico de w debe estar en proporción directa con n. o Correcto. Es deseable demostrar que el traductor funciona correctamente sobre todas sus entradas, a partir de un conjunto pequeño de pruebas. 2.5.2.2 Traducción dirigida por la sintaxis [Aha981 La traducción de lenguajes libres de contexto puede ser guiada por una GLC. Esto se logra proporcionando información semántica a las construcciones del lenguaje a traducir. Es decir, se asocian reglas semánticas a las producciones gramaticales y opcionalmente atributos a los símbolos no terminales. Hay dos notaciones para asociar reglas semánticas con producciones gramaticales: las definiciones dirigidas por la sintaxis (DDS) y los esquemas de traducción (STDS). En el proceso conceptual de traducción, tanto para las definiciones dirigidas por la sintaxis como para los esquemas de traducción, se hace un análisis sintáctico de la cadena de componentes léxicos de entrada, se construye el árbol de análisis sintáctico y después se recorre el árbol para evaluar las reglas semanticas en sus nodos, como se aprecia la Figura 2.2. La traducción de las cadenas de componentes léxicos es el resultado obtenido al evaluar las reglas semánticas. Una implementación no tiene que seguir al pie de la letra el esquema de la Figura 2.2. Hay casos especiales de definiciones dirigidas por la sintaxis en las que se pueden implementar las evaluaciones sintácticas en una sola pasada, sin construir explícitamente un árbol de análisis sintáctico o un grafo de dependencias entre atributos. 26 Cadena de entrada + Árbol de análisis sintákico + Grafo de dependencias + Orden de' evaluación de las reglas semántica gramática libre del contexto para especificar la estructura sintáctica de la entrada. A cada símbolo de la gramática ie asocia un conjunto de atributos y a'cada producción un conjunto de reglas semánticas, para calcular 'los valores de los atributos asociados con los símbolos que aparecen en esa producción. Las dependencias entre los atributos serán representadas mediante un grafo de Regla Semántica expr.a := expr1.a digit0.a expr.a := expr1.a digit0.a expr.a := digit0.a digit0.a := O + - ... digit0.a := 9 Tabla 2.1 Definición dirigida por expresiones de suma y resta de posfija. CAPhum 2: MARCO TEÓRICO - , 2.5.2.4 Asociación de atributos en una definición dirigida por la sintaxis En una definición dirigida por la sintaxis, cada producción gramatical A -+ a tiene asociado un conjunto de reglas semánticas de la forma b = f (ci, CZ,..., ck), donde f es una función; y, 1. b es un atributo sintetizado de A y CI,c2,..., ck son atributos que pertenecen a los símbolos gramaticales de la producción, o bien 2. b es un atributo heredado de uno de los símbolos gramaticales del lado derecho de la producción, y C I c2,..., ck son atributos que pertenecen a los símbolos gramaticales de la producción. En cualquier caso, se dice que el atributo b depende de los atributos c1 CZ, ..., ck. 2.5.2.5 Esquemas de traducción dirigidos por la sintaxis (STDS) [San981 Existe otra manera para traducir dos lenguajes entre sí: el esquema de traducción dirigida por la sintaxis. Este esquema es una gramática que asocia ciertos elementos de traducción con cada una de sus reglas gramaticales, intercalados en los lados derechos de dichas reglas. La traducción se realiza de un lenguaje descrito por la gramática a otro lenguaje definido por los elementos de traducción. Los elementos de traducción son también conocidos como acciones semánticas [Ah0981 que definen la equivalencia entre las oraciones de los lenguajes, al generar cadenas de salida a partir de cadenas de entrada. Las cadenas de entrada son porciones de oraciones que se derivan de la gramática. Las cadenas de salida son las cadenas de entrada traducidas. Un esquema de traducción dirigido por la sintaxis (STDS) es una 5-tupla T = ( N, E, A, R, S ) donde: N es un conjunto finito de símbolos no terminales C es un alfabeto finito de entrada A es un alfabeto finito de salida p E (N R e s un conjunto finito de reglas de la forma A-+a,P. Donde a E (N u I)*, u A)*, y los símbolos no terminales en p son una permutación en a de los no terminales. S es un símbolo no terminal distinguido en N, llamado símbolo de inicio. 2.5.2.6 Asociaciones entre símbolos no terminales dentro de reglas de producción Sea A+ a$ una regla de producción. A cada no terminal de a hay asociado un equivalente en p no terminal. Si un no terminal B aparece en a y p sólo una vez, entonces es obvia la asociación. 28 . 1 . CAPÍTULO2: MARCOTEÓRICO BASE TEÓRICA DEL ANÁLISIS DE CÓDIGO Si B aparece más de una ve se utilizan superíndices enteros para indicar la asociación. Esta asociación es parte íntima la regla. Por ejemplo, en la regla A+ B1CB2,B2B1C, las tres posiciones en B‘CB~se aSocian con las posiciones Y, 3” y l a respectivamente en B’B’C. I 2.5.2.7 Formas de traducción Una forma de traducción T se define de dos formas: 1. (S, S) es una forma de traducción, y se dice que las dos S están asociadas 2. Si (aAP, a’AP’) es una forma de traducción, en la cual las dos ocurrencias de A están asociadas, y si, A-+ y,y’es una regla contenida en el conjunto R (ver sección 2.5.1.5), entonces (ayP,a’y’P’)es a su vez, también una forma de traducción. Tanto, los no terminales y y I’como a P y a’P’ se asocian en la forina de traducción exactamente como están asociados en la regla, o bien, se utilizaran superíndices enteros (ver sección 2.5.1.6). Si las formas de traducción (aAP, a’AP’) y (ayP,a’y’P’) junto con sus asociaciones, son relacionadas como se describe en el párrafo anterior, entonces se escribe: (aA,P,a’AP’) a (ayp,a’y’P’) La traducción definida por T, denotada por T(T)es el conjunto de pares: {(%Y) I (S, S ) * (y, Y), =E* Y YEA*) 2.5.2.8 Derivaciones de formas de traducción Dada una cadena de entrada x se encuentra alguna derivación de x desde un símbolo inicial S utilizando las producciones de esquema de traducción. Suponiendo que S = a,~,“ ai,+= aZ, ..., a. = x, es una de tales dehaciones. Entonces, se crea una derivación de formas de traducción: (ao,PO)5 (ai,PI ) = (az, =-...-(an, Pn) P2) CAPITULO 2: MARCOTE~RICO ,. .~. tal que, (w,p 0 ) = (S, S), (a,,$") = (x, y), y -cada pi se obtiene-aplicando a pi., el elemento de traducción o la acción semántica correspondiente al ir de a i.1 a a i. La cadena y es una salida para x. 2.5.2.9 Ejemplo del uso de un STDS Considérese el siguiente esquema de traducción mostrado en la Tabla 2.2: Producción Elemento de traducción E=>E+T E=>T T=>T*F T=>F 5) F = > ( E ) 6) F=>digito 7) digito=>O 1) 2) 3) 4) 16) digito => 9 16) digito = 9 E=ET+ E=T T=TF* T=F 5) F E E 6) F=digito 7) digito=O 1) 2) 3) 4) ... ... Tabla 2.2 Esquema de traducción dirigido por la sintaxis que traduce expresiones aritméticas de suma y multiplicación, de notación en infijo a posfijo. El primer elemento de traducción indica que la traducción asociada con el símbolo no terminal E de la primera producción es ET+;el segundo elemento de traducción muestra que la traducción asociada con el símbolo no terminal E de la segunda producción es T, y así sucesivamente. ¿Cuál será la salida para la entrada w = 2+3*5?. Primero se encuentra una derivación por la izquierda de w desde E, utilizando las producciones del esquema de traducción. Entonces, se calculan las derivaciones correspondientes a las formas de traducción como sigue: (%E) ( E + T, E T + ) ( T + T, T T + ) (F+T, F T + ) ( digito + T, digito T + ) ( digito + T * F, digito T F * + ) ( digito + F * F, digito F F * + ) ( digito + digito * F, digito digito F * + ) ( digito + digito * digito, digito digito digito 3 3 * 3 3 3 3 * +) 30 ==? 3 (2+3 * 5,2 3 5 * +) * CAPÍTUL.0 2: MARCO TEÓRICO .!l. BASE TE6RICA DEL ANALISISDE CÓDIGO ,sin un análisis profundo. investigar formas de facilitar la integración de pursers ad hoc con herramientas de ingeniería inversa. CAP~TULO 2: MARCOTE~RICO La integración de ingeniería inversa en SOODA representa un caso ejemplo de las ideas en la cita de Müller et al. Por un lado, se eligió un STDS (revisar la sección 2.5.2) como fundamento teórico para traducir código en C++ ai lenguaje del diagrama de clases del UML'O. Por otra parte, se seleccionó ei h t i r como ia tecnología que permitió construir el analizador sintáctico del InverSOODA. Sin embargo, se necesitó idear una manera para facilitar la integración del analizador con el resto de la aplicación. En el capítulo 3 se aborda cómo se realizó dicha integración. Sólo se mencionará por ahora que se echó mano de algunos patrones de diseño. 2.7 Patrones de Diseño Orientados a Objetos El diseño y la instrumentación de un software orientado a objetos es sin duda una tarea complicada, siempre y cuando se recurra a la tradicional forma de construir software: el continuo redescubrimiento y reinvención de conceptos centrales que dan solución a problemas recurrentes. Una solución que mitiga la complejidad de la implementación de aplicaciones orientadas a objetos es recurrir a la reutilización de componentes de software o de clases desde las bibliotecas de clases. AI reutilizar ciertas clases y objetos se pueden construir complejas aplicaciones eficazmente. No obstante, el diseño embebido dentro del software con las características anteriores, se traduce en un sistema que refleja las necesidades actuales pero no necesariamente las necesidades futuras. Afortunadamente, los patrones de diseño orientados a objetos ayudan a identificar las abstracciones menos obvias que pueden ser representadas en objetos. Por ejemplo, los objetos que representan un proceso o algoritmo que no ocurre en la naturaleza y, sin embargo, son parte crucial de un diseño flexible. Los objetos de este tipo rara vez se encuentran durante la fase de análisis o aún en las primeras etapas de la fase de diseño; son descubiertos después durante la tarea de hacer un diseño más flexible y reusable. Pero, (,qué es un patrón de diseño? El concepto de patrón común de diseño fue introducido en 1988, con el Model-View-Controller (MVC) para Smalltalk. Sin embargo, un reconocimiento más completo del concepto de patrones de diseño orientados a objetos, fue madurado durante la primera mitad de la década de los años noventa principalmente por Erich Gamma: "Los patrones de diseño orientados a objetos describen soluciones simples y elegantes hacia problemas específicos en el diseño orientado a objetos". "Son soluciones recurrentes a problemas de diseño que se presentan una y otra vez" [Gam951 'O Pana [Par001 propone una gramática que genera el lenguaje visual del diagarna de clses del UML. 32 ri ,.j. CAPiTULO 2: MARCO TE6RiCO 2.7.1 PATRONES DE DISENOORIENTALXX A OüETOS Un nivel de abstracción más alto que el concepto de clase [Gam951 h Por su parte, InverSOODA cue ta con un diseño arquitectural de clases que ya incluye algunos patrones de diseño que bromueven el reuso de funcionalidades básicas y la integración de otros módulos de la Tnángvlo Escslcno Triángulo Equilálcm 33 Tningulo Ishecles CAPhTJLO 2: MARCO TE6RlCO 2.7.3 Representación de estructuras todo-parte con el patrón de diseño Composite IGam95j La intención de dicho patrón es la de componer objetos dentro de estructuras de árbol para representar jerarquías de tipo todo-parte. Su uso se extiende principalmente a aplicaciones de gráficos como editores de dibujos y procesadores de texto, donde el usuario puede agrupar elementos gráficos para formar otros más complejos. Utiliza la composición recursiva en términos orientados a objetos. La clave en el patrón de diseño Composite es una clase abstracta que representa ambas clases primitivas y sus clases contenedoras. En la Figura 2.3 de la pá ina anterior se ejemplifica una estructura Composite: la jerarquía de figuras geométricas , que contiene a la superclase abstracta Triángulo y sus subclases Triángulo Escaleno, Triángulo Equilátero y Triángulo Isósceles. 5 La aplicabilidad de este patrón se da cuando: Se quieren representar jerarquías todo parte de objetos. Se quiere que los programas cliente ignoren la diferencia entre composiciones de objetos y objetos individuales. Los programas cliente tratarán todos los objetos en la estructura Composite de manera uniforme. La estructura general del Composite identificada por Gamma, se muestra en la Figura 2.4. - Composite Operation0 Add(Componente) Remove(Com ponente) GetChild(Componente) Figura 2.4 Estructura general del patrón de diseño Composite. " Una variación del clásico ejemplo de la pmgramaci6n oricnrada aobjelos: la clase figura y sus subripas cuadrado, recfangulo, rombo. circulo, etc. 34 CAPITULO 2: 2.7.4 MARCO TEÓNCO PATRONES DE DISEÑO ORIENTADOS A OBJETOS i El patrón de diseño Bui der para creación de objetos compuestos IGam9SI. El patrón de diseño Builder tkne la siguiente intención: Separar la construcción de un objeto complejo de su representahn, tal que el mismo proceso de construcción pueda crear diferentes representaciones. Su aplicabilidad se establece cua complejo debe ser in$ependiente de las partes que El algoritmo que crea un forman el objeto y cómo sk ensamblan. El proceso de construccióh debe permitir diferentes representaciones para el objeto que se está construyendo. 1 La Figura 2.5 comúnmente es patrones fueron diagramas de clase en uso práctico de los patrones también utilizados. builder->ConctruiiPaite() de diseño Builder. Un objeto Builder Composite (ver sección 2.5.3); ambos de representación y construcción interna de los En el siguiente capítulo, ,se aborda con más detalle el Composite y Builder, además de algunos otros ConstiuirParteO ---m Figura 2.5 Estructu a general del patrón de diseño Builder. I 2.8 Referencias CAPhWu,2: MARCO TE6RICO [Big891 Biggersiaff, Ted J. Design Recovery for M&tenance and Reuse Computer. (E.U.: IEEE Computer, Julio de 1989) pp. 36-49. (Chi901 Chikofsky. Elliot J. [y] Cross (I;James H. Reverse Engineering and Design Recovery: A Taxonomy. (E.U.: IEEE Sollware. Enero de 1990) pp. 13-17. [Gam951 Gamma Ench et al. Design Patterns-Eiements of Reusable Object Oriented Software. (E.U.: AddisonWesley-Longman.1995) pp. 3-31.97 163. [ltC03] Instituto Tecnológiw de Ciudad Guzmán. Diserío detallado httl)~ilWWW.itw.edu.mx/inQsofUdetalla.hlm19 Febrero de 2003. [Joh93] Jonson. J . Howard. .identifyng Redundancy in Source Code using Fingerprints. (Canadá: Proceedings of CASCON '93. Toronto, Ontario. Octubre de 1993) pp. 171-183. ~JOY901 Joyanes Aguilar. Luis Fundamentos de Programación. Aigoritmos y Estructuras de Datos. (México: McGrawhilüinteramencana de México S.A. de C.V.) pp 511, 519. [LOP021 Lbpez Sanchez. Maximo. Protocolo de proyecto a CONACYT. (Propuesta de proyecto sometida al CONACYT (con formato en documento electrónico). Cuernavaca. Morelos. México, CENIDET. G ~ p de o lngenieria de Software, Octubre de 2002). [MüiOO] Müller. Hausi A. et al. Reverse Engineering: A RoadMap. htto:iiwww.cs.ucl.ac.uMstaffA.Finkelstein~ose~nalmuller.~f, Mayo 2000) 12 páginas. [ParOO] Parra Ramlrez, Isaac A. Modelado Wsual Orientado a Objetos. (Tesis de Maestrla. CENIDET. Cuemavaca. Morelos, Méuw. Diciembre del 2000) pp. 6.2, 1.6. A3. [PreOZ] Pressman, Roger S. lngenieria del Sofiware. Un enfoque práctico. Quinta Ed. (Madrid. España: McGrawhillilnteramericana de España, 2002) p. 546. [Pia951 Plaitini. Mano [y] D&yanani Sunil. Elementos y Herremientas en el Desarmiio de Sistemas de Informacibn. Una visión acfual de la tecnolcgia CASE. (Madrid. EspaRa: McGrawhillilnteramencana de España - Rama, Serie Paradigma. 1995) p. 42-45 [RurnOl] Rumbaugh James e l al The Unifiod Modeling Language Reference Manual (Indianápolis. IN E U AddisonWesley Pearson Education. Agosto de 2001) [San961 Santaolaya Salgado. René Apuntes sobre compiladores (Cuernavaca. Morelos, México: CENIDET Junio. Diciembre de 1998). [SchOO] Schmuller Joseph. Aprendiendo UML en 24 horas. (México: Pearson Educaci6n de México. S.A. de C.V., la Edicibn, 2000) pp. 99, 134. Wen021 Wences Dlaz. Martha F. Modelo de ingenieria inversa para la obtención de 'diserío detallado basado en LEVISS. (Tesis de Maeslria. CENIDET. Cuernavaca. Morelos. México, Febrero de 2002). [ZarnOl] Zamudio Lbpez. Sheidy A. Ideniificacibn de Funciones Recurrentes en Sohare Legado. (Tesis de Maestrla. CENIDET. Cuemavaca. Morelos. México, Diciembre del 2001) p. 26. 36 (Canadá: Capítulo 3 “¡No hagas todo por mí, Emacs” K.Rodarmer 3.1 3.2 3.3 3.4 3.5 3.6 3.7 Introducción Arquitectura de InverSOODA Diagrama de clases de In\;erSOODA I Aspectos de diseño orientados a objetos Los analizadores de código fuente 1 Interacción con InverDDVi Referencias 3.1 Introducción Un modelo conceptual es una representación 1 de aito nivel de cómo se organiza y opera un determinado sistema. Involucra las más importantes metáforas y analogías empleadas en el diseño, los conceptos que el siskema expone a los usuarios, las relaciones entre dichos conceptos, los mapeos entre esaos conceptos y dominio de tareas que el sistema está diseñado a soportar [Dan02]. El lect r encontrará en este capitulo cuestiones sobre el diseño y arquitectura de InverSOODA, las estrategias de ingenieria inversa, la interacción con InverDDVi y el rediseño de la arbuitectura original de SOODA, y se describen con cierto detalle algunos aspectos que comF/lementanla comprensión del sistema. P I 3.2 Arquitectura de InverSOODb La Figura 3.1 muestra la arquitec&a general de InverSOODA vista por capas de servicios'. He aquí su descripción: I I servicios en la primera capa a través de la interfaz a) Un usuario utiliza los siguientes gráfica de usuario de inver OODA LT J J J Creadiagramas de claseS y diagramas de diseño detallado. Genera archivos en medios persistentes que contienen el código fuente en C t t correspondiente a los di gramas de clases. Almacena la lógica de los diagramas en,medios persistentes. fuente en C++ existente para obtener los los objetos del ANTLR y los objetos de soporte a, los servicios de la primera conjunto de mensajes que procesan información generada por pos eventos de usuario. En esta capa se determina el comportamiento dinámico d$ los objetos del sistema. b c) Finalmente, la tercera capa u ica los servicios del sistema operativo como el Último escalafón del conjunto de capas de software de InverSOODA. El sistema operativo puede ser Windows 9x, Windows Me O Windows XP Home. 1s palabra scrvicio con algún otra significado compuiacianal que arbitrano p a n ejemplificar de mancra no convencional 18 39 CAPfTULO 3: EL MODELO CONCEPTUAL DEL SISTEMA lnteriaz Código fuente en C++ Usuario 1. Capa 2' Capa . ... .-. . ., . i . I Figura 3.1 Arquitectura de InverSOODA vista por capas de servicios. 3.3 Diagrama de clases de InverSOODA Recordando las ideas del segundo capítulo en la Sección 2.3.1 de este documento: *...un diagrama de clases provee la vista estatica de un software orientado a objetos y siempre debe ser dibujado para una aplicación orientada a objetos". La Figura 3.2 muestra las principales clases de InverSOODA. 40 CAPhULO 3: I EL MODELO CONCEPTUA, - + DEL SISTEMA DIAGRAMA DE CLASES DE XNnRSOODA 1 1 1 Ij '1 I :, . ............ ~ ........... I 71, I 41 CAPÍTULO 3: .. ELMODELO CONCEPWAL DEL SISTEMA 3.4 Aspectos de diseño orientado a'objetos La siguiente sección describe los aspectos de diseño orientado a objetos tomados en cuenta para el rediseño de SOODA. Esto es, los aspectos de diseño que hicieron posible la. incorporación de la nueva funcionalidad provista por InverSOODA. Se hace énfasis en las partes de la arquitectura de InverSOODA en donde se aplican patrones de diseño orientados a objetos, aunque también se menciona la aportación de las clases de la Biblioteca de Clases Base de Microsoft, la MFC. 3.4.1 El Diseño de Aplicaciones MFC Relevante es hablar de la biblioteca de clases llamada MFC (Microsoft Foundation Classes), debido a que originalmente SOODA e InverDDVi se basaron en ésta y a que InverSOODA continúa utilizándola. La MFC es una biblioteca propia del entorno de desarrollo Visual C++ de Microsoft. El uso de la MFC estnba en ayudar a desarrollar aplicaciones de C++ para Windows 32 bits tratando de lograr los siguientes objetivos [parno]: - Reducción de la cantidad de código escrito para una aplicación en Windows. Habilidad para llamar a cualquier función de C directamente. Conversión de aplicaciones en C a Cti-. Facilitar el uso d e la interfaz de programas de aplicación ( M I ) de Windows al utilizar caractensticas de C+t. 3.4.2 Arquitectura documento-vista Cuando se utiliza el asistente de generación de aplicaciones de Visual C t t (AppWizard) se puede escoger la generación de una aplicación tipo MFC entre otros tipos de aplicaciones para Windows. Una aplicación generada como aplicación MFC tendrá necesariamente la arquitectura documento-vista. Dicha arquitectura incorpora dos clases principales: a) La clase documento. Corresponde a la clase que manipula la información que el usuario puede guardar desde la aplicación. b) La clase vista. Se encarga de manipular la manera en que se presenta la información al usuario y de procesar los eventos de entrada. 42 , C A P ~ U L3:OEL MODELO CONCEPTUAL DEL SISTEMA Figura 3.3 Relación entre 1 -. ._ _ j ASPECTOS DE DISENOORIENTAW A OBJETOS una aplicación MFC I) La conformación de entidades de código organizadas más entendibles y de fácil mantenimiento. No obstante existe un problema Potencial con el uso de la MFC: se pueden agregar a el usuario sin un esquema de reusabilidad. una aplicación MFC clases En las siguientes objetos, como una que se tiene de el uso de patrones de diseño orientados a posibilidad de perder la escalabilidad y reuso . CAP~IJLO3: EL MODELO CONCEP~UAL DEL SISTEMA 3.4.3 Uso de los patrones de diseño Composite, Iterator y Visitor 3.4.3.1 Motivación La aplicación del patrón de diseño Composite no difiere mucho del ejemplo clásico que aparece en el capítulo dos del libro de Eric Gamma [ G ~ ~ ~que S I , trata del diseño de un editor de documentos, mejor conocido como procesador de texto. De hecho, los criterios de diseño tomados de dicho capitulo son casi idénticos. La diferencia está en la funcionalidad de SOODA, que mucho dista de ser un procesador de textos para enfocarse al modelado visual de sistemas orientados a objetos. Lo mismo ocurre para InverSOODA, pues su interfaz gráfica de usuario y su estructura interna de documento están basados en SOODA. A partir de que en SOODA se identifica un caso típico de diseño que involucra una estructura de documento, se aplica el patrón de diseño Composite. Aunado al aspecto anterior, está el recorrido de dicha estructura por medio de objetos Iterator. Es decir, los datos de los diagramas están almacenados en una estructura de datos que puede ser recorrida de vanas formas. Además, se utilizó experimentalmente el patrón de diseño Visitor para efectuar acciones específicas durante el recorrido en cada nodo de la estructura Composite. InverSOODA utiliza diferentes objetos visuales para desplegar los diagramas de clases: rectángulos, líneas, flechas, texto. El usuario de la aplicación utiliza estos elementos visuales para conformar sus diagramas, o bien realiza ingeniería inversa, lo cual trae como resultado los diagramas de clases con los objetos visuales correspondientes al diseño del código. ¿Cómo se tratan internamente estos objetos visuales?, ¿Cómo hacer para que un objeto visual llamado Flecha tenga su correspondiente objeto en el diseño de la aplicación?. Estas dos respuestas aforíunadamente ya tenían resultados desde SOODA IPdo1. Pero, ¿cómo hacer que un objeto parser generado con ANTLR pueda manejar transparentemente un objeto Flecha a manera de un objeto más abstracto denominado Grafico?, o, ¿cómo hacer que un objeto Diagrama derivado de Grafico se trate igual que los objetos tipo Grafico que contiene?. La repuesta a estas preguntas es utilizar algún tipo de estructura de datos para representar jerarquías de objetos todo - parte. El patrón de diseño Composite permite tratar los objetos dentro de este tipo de jerarquías uniformemente y casi siempre vienen asociados los patrones de diseño Iterator y Visitor para hacer recorridos y acciones variantes cuando se visita cada nodo de la jerarquía de objetos compuestos. 3.4.3.2 Aplicabilidad Gamma [carn95]recomienda utilizar los patrones Composite, Iterator y Visitor en las siguientes circunstancias: A) Composite 1) Cuando se quiere representar jerarquías de objetos todo -parte 1. CAr'hULo 3: ELMODELO C O N C E m A DEL S l S E M A d ASPECTOS DE DISENO ORLENTADO A OBJETOS 2) Se quiere ignorar la diferencia.entre composiciones de objetos y objetos individuales y trat r ambos tipos uniformemente. 1 B) Iterator I) Acceder el conten'do de un objeto agregado en estructuras Composite (o simplemente en li tas o vectores de objetos) sin exponer la representación interna de dicho objeto. 2) Se quiere múltiples formas de recorrido de listas o vectores de objetos.. uniforme para realizar los recomdos (iteración polimórfica). 7. C) Visitor Una estructura de Composite contiene muchas clases de objetos con interfaces quiere efectuar operaciones en dichos objetos que dependen de su imp ementación concreta. Se necesita efectua, muchas operaciones o acciones sin relación alguna de objetos contenidos n una esmictura de datos,' y no se quiere modificar o extender la impiemehtación de dichos objetos con las operaciones o acciones directamente. El p h n de diseño Visitor mantiene estas operaciones encapsuladas en ud objeto aparte y sabe llevarles la acción de dichas operaciones a los odjetos agregados en la estructura de datos, por medio de o double-dispatch p r n 9 5 ] . un mecanismo la estructura de objetos cambian muy de vez en cuando. t 'k 18 InverSOODA sólo se explica de esa manera. Recuerde el lector que no es propiamente la intención del proyecto justificar o demostrar ,el uso de determinado patrón para algo, simplemente es una cuestión de conyeniencia y buen gusto por la tecnología de objetos. N O obstante, se encontraron resultados interesantes, mismos que se comentan en la Sección 3..4.3.4. CAph'WO 3: ELMODELO CONCEPTUAL DEL SISTEMA 3.4.3.3 Colaboraciones La Figura 3.4 muestra al patrón de diseño Composite junto con los otros dos patrones descritos en esta sección2. I' Figura 3.4 Diagrama de clases con los patrones de diseño Composite, Iterator y Visitor embebidos en la arquitectura de InverSOODA. Enseguida se describen las colaboraciones de las clases involucradas en los tres patrones en cuestión: Composite: o CGrujco: Es la clase abstracta en el tope de la jerarquía del Composite. Es la clase padre de toda clase que represente una entidad grafica en InverSOODA. Su interfaz permite que las clases hijas redefinan operaciones como Dibujar: un objeto rectangular evidentemente se dibujará en pantalla de manera diferente que una línea por ejemplo; pero también incluye métodos que le permiten establecer relaciones con objetos tipo Iterator y Visitor. Concretamente, CreurIterudor permite que cada clase hija cree o no su propio objeto Iterato? y Aceptar, cuya intención es que las clases hijas compuestas o simples puedan apegarse al patrón de diseño Visitor. Algunas c l a s s del código fuente sc omiten por cumtiones de Sspacio, pero aparecen las más importantes. ' Tomando cn cuenta que los objetos del patrón Composite pueden ser simplcs o compuestos. para lor primems se crea por dcfceto u? objeto ltirator que itera en el vacio, caso contrario para los objetos compuestos, que pueden crear un objeto ltcrator a la medida de sus ePtNeNmS de datos. 46 *'+. CAPITIJLQ3: ELMODELO CONCEPTUALPEL SISTEMA I. - ..) , 47 .- ASPECTOS DE DEERo ~ - - - . - . A osmos . - CAF’fTULO 3: E L M O D E M CONCEPTUAL DEL SISTEMA objetos Visitor. No redefine la creación de objetos Iterator pues es un objeto simple dentro del patrón de diseño Composite. Iterator: o Crierator CCGraJco*>: Es una clase abstracta parametnzada con apuntadores a objetos de tipo CGrafico. Define en su interfaz los métodos necesarios para recorrer estructuras Composite de tipo CGrafico. El recomdo de objetos simples se realiza iterando en el vacío. El recomdo de objetos compuestos se realiza dependiendo del objeto Iterator concreto que definan dichos objetos compuestos. El uso de templates de C t t en el patrón de diseño Iterator obedece a que la estructura de datos utilizada para definir el patrón Composite también debe ser parametrizada. Cada objeto compuesto es capaz de crear objetos Iterator concretos específicos a sus necesidades de recorrido. o CListIterator <CGraJco *>: Es una implementación concreta de la clase Citerator. En InverSOODA es el Iterator por defecto para objetos compuestos tipo CDiagrama. Realiza un recorrido lineal de la .estructura de datos del objeto diagrama. Visitor: O CKiitor: Es una clase abstracta de la cual se pueden extender clases concretas CVisitor especificas al patrón de diseño Composite utilizado en InverSOODA. Su existencia obedece a definir una serie de métodos virtuales que corresponden cada uno a las clases concretas del Composite mencionado. Si durante el recorrido de la estructura Composite se ve involucrada una acción específica hacia un objeto, digamos de tipo CClase, entonces la implementación concreta del método VisitCClaseO sabe exactamente que sólo objetos de tipo CClase pueden recibirlo en su método Aceptar 0. No hay manera de confundir al compilador pues la firma que define CVisitor es Única para cada objeto Composite. Normalmente, los objetos Visitor comienzan su visita al Composite apoyándose del Iterator que crea CDiagrama. El primer objeto que visita depende de qué posición se encuentre en la lista de objetos simples del objeto diagrama. o CApunfador: Esta clase es una implementación concreta de CVisitor y sirve para ejecutar la acción específica que corresponda a un objeto componente del Composite. Cuando el usuario de la aplicación ha pulsado un botón del ratón, estando la aplicación en modo apuntador, una acción específica será llevada a cualquier objeto simple del patrón Composite que pueda responder a ella. Así, la colaboración se da en el escenario dinámico entre objetos Composite cuyo estado podrá o no ser modificado y el objeto apuntador que lleva la acción modificadora a dichos objetos Composite. , . O CDblClick: Esta clase también es una implementación concreta de CVisitor. Cada implementación de los métodos de CDblClick encapsula la semántica de ejecución específica para’ cada objeto Composite, a partir de un evento de doble pulso de 48 puntero asociado con cierto objeto en la estructura de datos. 3.4.3.4 Consecuencias CAPhULO 3: EL MODELO CONCEPIUAL DEL SISTEMA 2. El uso de templates de C++ para parametrizar objetos Iterator permite mantener una relación con la clase CGrafico y todos sus descendientes: Un objeto Iterator siempre devolverá un puntero a CGrafico cuando se encuentre recomendo un objeto compuesto y esto supone una ventaja cuando se llaman solamente los métodos de la interfaz de CGrafico. Sin embargo, cuando se necesita saber con exactitud qué clase se está obteniendo desde la estructura de datos, entonces es necesario recurrir al RTT?, o a las macros de la MFC (RUNTIME-CLASS), o bien al uso de objetos Visitor. Las consecuencias de usar el patrón de diseño Visitor son: 1. Permite añadir nuevas operaciones que dependen de los componentes de objetos complejos Composite. Por ejemplo, se puede definir una nueva operación obtener nombres de clases definiendo un nuevo objeto Visitor concreto que obtenga los nombre de todas clases que conforman un diagrama en InverSOODA. Lo interesante de esta cuestión es que no se necesita cambiar ni añadir nuevo estado ni implementación en las clases Composite para que la nueva operación funcione. El nuevo objeto simplemente va obteniendo los nombres de cada clase cuando visita objetos de tipo CClase. 2. Los objetos Visitor pueden ir acumulando valores estado, que de otra manera tendrían que estar pasándose como argumentos en los métodos que efectiian el recorrido de estructuras Composite. 3 . El uso de objetos Visitor de alguna manera rompe con el encapsulamiento de los objetos que visitan, pues para acceder al estado privado de estos Últimos necesita ser declarado comofn’end. 4. No es fácil añadir una nueva clase concreta Composite que responda a los objetos Visitor pues se tendría que añadir un método virtual para cada uno de dichos objetos Visitor. Esto podría implicar un gran esfuerzo si ya existen numerosas clases concretas derivadas de CVisitor. 3.4.4 Usa del patrón de diseña Builder cama base para construir el diagrama de clases 3.4.4.1 Motivación El proceso de construcción de un diagrama de clases en SOODA es asíncrono. El usuario usa una barra de modelado con la cual se pueden escoger pequeños símbolos gráficos que representan las diferentes figuras que conformarán el diagrama de clases. Todo esto sucede en intervalos asíncronos de tiempo como se observa en la Figura 3.5. ‘Run Time Type Infamation 50 - CAPhlJLO 3: EL MODELO CONCEPTUAL ASPECTOS DE DISEÑO OMENTAD0 A OBJETOS I La principal consecuencia de a construcción asíncrona de un diagrama, es que impacta de manera directa en el diseño ¿e los mecanismos que responden a eventos asíncronos. Hablando en términos generales, la solución más común a la construcción asíncrona de diagramas inicia con el procesamiento de información tomada directamente desde eventos de ratón o de teclado. I Barra de modelado de SOODA Evenlol: crear Clase ... Eventon-I: Crear clase ~wnb,: Crear herehcia Eventos aslncronos Construcción del diagrama de clases Representación Visual .I Figura 3.5 Construdción asíncrona del diagrama de clases. 1 Por otra parte, la construcción del diagrama de clases visto desde un proceso de ingeniería inversa es síncrono. La Figura 3.6 ilustra dicho proceso: se puede visualizar la creación inversa como una máquida constructora, que asciende a través de un árbol sintáctico de derivación sincronizaddo la toma de información obtenida en cada hoja o nodo intermedio del árbol, desde sintácticos o de acciones semánticas. La información necesaria para realiza inversa viene entonces desde un flujo síncrono de tokens, que termina con un carácter EOF en el nodo raíz del árbol sintáctico. De lo anterior se deduce que manera síncrona o asíncrona. dos formas de construir un diagrama: de sí mismo, que se representa lógicamente En InverSOODA el y cada objeto contenido encapsula a su con un objeto vez las características de cada gráficd del diagrama. El diagrama intrínsicamente mantiene I CAPITULO 3: EL MODELO CONCEPTUAL DEL SISTEMA una composición de objetos, es decir, es un Composite (ver sección 3.4.3). Se puede hablar de que el diagrama es en sí un objeto complejo compuesto por muchos otros. Obieto Parser Código fuente - Infomacdn sincrona desde acciones semanticar Area de Aplicaclón de SOODA 88888 O " O Construcción del diagrama de clases Representación Visual Figura 3.6 Construcción síncrona del diagrama de clases. ¿Cómo construir un diagrama Composite de manera síncrona o asíncrona manteniendo una interfaz abstracta común para la construcción de diferentes diagramas?. Una forma adecuada es aplicando el patrón de diseño denominado Builder. 3.4.4.2 Aplicabilidad Se recomienda usar el patrón de diseño Builder cuando [cam9S1: I ) El algoritmo para crear un objeto complejo debe ser independiente de las partes que conforman el objeto y de cómo se ensamblan. 2) El proceso de construcción debe permitir diferentes representaciones para el objeto que se construye. El algoritmo síncrono para construir los diagramas de clases en InverSOODA es independiente del algoritmo asíncrono. El primero resuelve la obtención de información desde las acciones semánticas del objeto parser generado con ANTLR, y el segundo toma información desde eventos de ratón y teclado. Además, el proceso de construcción permite construir, ' potencialmente, diferentes representaciones para un objeto diagrama en particular, por medio de diferentes objetos Builder concretos. La Figura 3.7 muestra un 52 CAP~TULO3: EL MODELO ASPECTOS DE DISEROORIENTADOA OBJETOS h diagrama de clases de U M L co las actuales clases involucradas en el patrón de diseño Builder embebido en la arquitecdra de InverSOODA. Figura 3.7 Diagrama de clase UML del patrón de diseño Builder embebido en la arquktectura de InverSOODA. I 3.4.4.3 Colaboraciones I clases de manera asíncrona; es guiado por el objeto CSoodaLButtonUp durante el proceso de construcción. 9 7 . CInverSoodaDiagramaBuild r. Es el objeto cuyos métodos construyen el diagrama de clases de manera síncrona, el objeto TinyCPPParser guía el proceso de 53 C A P ~ J L3:O EL MODELO CONCEFTJAL . DEL SISTEMA construcción por medio del preprocesamiento y envío de información semántica hacia dichos métodos. TinyCPPParser. Es el objeto que realiza el análisis sintáctico de código fuente y que por medio de acciones semánticas controla el protocolo síncrono de construcción del diagrama de clases, apoyado por el objeto CInverSoodaDiagramaBuilder. Y I I r n a a i r c n dlagama J< OnBvllonlnplnv ~ ,:i I I _____ ___- CrearMaIodo Crsadlrlbulo CraarCLiSs Amadir en d l a g r s m i I I Figura 3.8 Diagrama de secuencias UML de los objetos en el patrón Builder. 3.4.4.4 Consecuencias La interfaz.de la clase abstracta Builder permite ocultar la representación y estructura interna del objeto diagrama que construye, encapsulando también el proceso de construcción. En otras palabras, el código fuente de construcción y representación queda aislado de las demás clases de la aplicación. Sólo el objeto concreto Command (ver Sección 3.4.5) que responde al evento de levantar el ratón y el objeto purser (ver Sección 3.5) conocen el proceso y protocolos asíncrono ,y síncrono de construcción respectivamente. Dichos objetos representan los objetos directores mencionados por Gamma [ G ~ ~ S Por J . su parte, los objetos Builder concretos contienen la implementación apropiada para crear y ensamblar un diagrama de clases según el protocolo de construcción. Otra consecuencia del uso del patrón de diseño Builder radica en que se obtiene un control más granular del proceso de construcción del diagrama de clases, respecto a la construcción de golpe que proveen otros patrones de diseño de creación como el Factory Method [Gam951 o el Prototype [ G ~ ~ ~El s I patrón . de diseño Builder permite controlar paso a paso el ensamble de las diferentes partes que conforman un objeto diagrama y por consecuencia de la esmictura interna de este último. 54 .* , I ! CAPhWLO 3: ELMODELO CONCEPTUAL DEL SISTEMA ASPECTOS DE DISENO ORIENTADO A OBIETOS 3.4.5 Uso del patrón de diseño Command para eliminar dependencias entre la clase documento y la clase vista 3.4.5.1 Motivación evento. Por ciclo clásico de de un objeto manejador de Microsoft Windows. En eventos generados desde mientras que el El problema se presenta documento y la vista de implementaciones que documentos e incluso operaciones triviales bajo MFC, una vez para entonces extender la funcionalidad de la con que se implementaron los I capacidad de El esquema de de evento con algún que se le dé al método implícita del identificador de gráfica de usuario, se entra en el se selecciona un método específico intrinzado mapeo de mensajes de MFC, lo común es que los objetos vista respondan a barras de scroll y barras de herramientas, los elementos Lie la barra de menú. la interacción a nivel mensaje de objetos entre el MFC es altamente acoplada. Es fácil caer en dependencias entre objetos vista y objetos anterior no es probl'ema si la aplicación realiza fácil codificar una aplicación para Windows mensajes y el manejo de cuadros de diálogo, estatutos case y handlers con los que Sin embargo, cuando hay que es bastante dificil moaificar la intención original los objetos vista o documento. al método del objeto Vista que responde a Supóngase, que ' eventos de soltar un botón del ratón.I Dicho método originalmente ocasionaba que ciertas I variables se modificaran en el objeto documento, a partir de la coordenada en la que se este método tenga el mismo que tiene definida la clase Vista. con esta'situación, sin embargo, el más voluminoso y necesariamente código que modifiquemos y u objetos de la aplicación. Se corre el riesgo generará más dependencias funcionalidad métodos como OnBuffonUp. de que no sea tan trivial como Vista, manejador de eventos por orden específica para cierta semántica encapsulación de varias líneas código problema es el patrón de ¿ Que esquema defecto, pueda 55 CAF'hVLO 3: EL MODELO CONCEPTUAL DEL SISTEMA . . 3.4.5.2 Aplicabilidad Se puede hacer uso del patrón de diseño Command cuando [ G ~ ~ ~ s I : 1) Se parametrizan objetos que llevan implícita la acción a ejecutar. 2) Especificar, almacenar y ejecutar peticiones en momentos diferentes. Un objeto Command puede tener un tiempo de vida independiente de la petición original. 3) Permitir operaciones de deshacedrehacer. Un objeto Command puede almacenar el estado de ciertas variables para revertir el efecto de las operaciones del objeto realizadas. En la versión actual de SOODA sólo se aplica parcialmente el punto número 1; se dejó el mapeo de mensajes al estilo de la MFC, lo que implica que automáticamente se generen métodos con una firma preestablecida. Lo anterior no permite cabalmente aplicar la estructura de clases propuesta por E. Gamma respecto al patrón Command. Sin embargo, todos estos puntos fueron considerados originalmente antes de aplicar el patrón. 3.4.5.3 Colaboraciones , La gran diferencia entre la estructura original del patrón Command propuesta por Gamma y la adaptación que se realizó en InverSOODA consiste en que no necesariamente existe un objeto receptor ni otro emisor. CVista hace las veces de receptor e invocante pues no existe el concepto puro de objeto invocante en el mapeo de mensajes MFC, mas bien se manejan los identificadores constantes al estilo IDBUTTONl, ID MENU ITEM. Puesto en otras palabras, no se pueden mandar como parámetros objetos command en métodos dentro del mapeo de mensajes MFC, para ajustar a la medida del patrón Command en la arquitectura documento-vista, al menos no de manera trivial. No obstante, sí se logró implementar parcialmente el patrón Command al diseñar objetos que colaboran con el objeto Vista para tomar la responsabilidad de atender a los eventos de usuario. Concretamente, existe una jerarquía de objetos Command; una clase abstracta más una clase concreta por cada tipo de evento de ratón que maneje la clase vista. En la Figura 3.9 se aprecia cual es la vista estática de las clases involucradas con el patrón de diseño Command. 56 CAPhlJLO 3: EL MODELO CONCEPTUAL DEL SISTEMA CCommmd E@mla,() ASPECTOS DE DISENO ORIENTADO A OüJETOS -- - - --- - - - <-----.-.------((depends >> OnBunonDom () .. CSoodaLBvflOnüblClk ~ CSoodaLBu«onDown ~. i CSoodaLBultonUp C A f h J L O 3: EL MODELO CONCEPTUAL DEL SISTEMA 3.5.1 Creación de analizadores de código con ANTLR No es la intención de esta tesis proveer un tutorial sobre el manejo del ANTLR Sin embargo, se considera prudente y puntual mostrar al lector la manera básica con la que se especifica la creación de un analizador con la herramienta ANTLR. De tal suerte, se ayudará en la c.omprensión global de las siguientes secciones y particularmente al uso de acciones semánticas como mecanismo clave de la ingeniería inversa. Es bastante natural la creación de analizadores con ANTLR. Sólo se necesita conocer la notación Backus-Naur o BNF, las expresiones regulares y tener nociones de programación en los lenguajes C++ o Java. ANTLR permite especificar un analizador para un lenguaje determinado (libre de contexto) a partir de la gramática que genera dicho lenguaje. Los siguientes pasos describen un poco más a detalle el proceso de creación del analizador: 1. Identificar la gramática BNF que genere el lenguaje que se quiera analizar. La gramática debe ser de tipo regular o libre de contexto. 2. Escritura de la gramática de acuerdo a la sintaxis de especificación del ANTLR, en un archivo de texto: a) Producción gramatical. Cada símbolo no terminal que derive en otros símbolos se escribe a la izquierda, seguido de dos puntos ( e l caracter ‘:’ ), seguido de los símbolos terminales en los que deriva dicho símbolo no terminal. Se marca el fin de la producción gramatical con un carácter punto y coma ‘;’. Si existen más de dos derivaciones, se puede utilizar el caracter pipe ‘I>, para separar dichas derivaciones. b) Acción semúntica. Si las producciones tienen asociadas una acción semántica, entonces deberá especificarse inmediatamente antes del caracter de término ( ‘;’ ) un bloque especial encerrado entre llaves. 3. Procesar el archivo de texto con la especificación gramatical con la utilena Tool de ANTLR, esto generará uno o varios archivos con el código fuente correspondiente al analizador que reconoce oraciones de la gramática especificada. Ejemplo de gramática especificada para ANTLR: 1. Identificación de gramática ( N, T, So, P ) , donde : N = ( A, B , C ) T = ( a , b, c ) G = so = = s ( s + ABC, A + aA. A + a , B -+ b B , B + b , 58 c -f ac, c -fC ) 2. Escritura de la gramática bajo las reglas de ANTLR, dentro de un archivo de texto: / * Archivo gram header */ #include <stckio.h> ' 1 options { // 1 I aquí van opciones exclusivas para el / / una seccióh opcional para incluir código 1 class Lexer exte options {' / / más opciones exclusivas para ei ANTLR 1 s : i A : I B : I c : I i ABC aA a { printf bB b { printf i cc c { printf 1 'a" ) (I "b" 1 } } ( / * fin de archivo con el nombre grarnarica-ejemplo.g y se tenga instalado el intérprete de java en el sistema. I,, 59 CAPiTULO 3: EL MOOELO CONCEPTUAL DEL SISTEMA La Figura 3.10 de la página anterior muestra un sencillo ejemplo de archivo de especificación de gramática para ANTLR. Las producciones gramaticales se encuentran en negritas. Estas producciones gramaticales corresponden a las producciones P definidas anteriormente en el paso 1 del mismo ejemplo. Son bastante similares a una especificación en notación BNF. Por ejemplo: S : ABC; equivale en BNF a: < S > ::= < A B 0 El lector notará que también existen otros elementos dentro del archivo ejemplo como comentarios estilo C / C++, algunos bloques encerrados entre llaves, entre otras cosas. Los bloques encerrados entre llaves que preceden el caracter de cierre de producción gramatical ‘;’ son las acciones semánticas. Por ejemplo: B : bB I b { printf ( “b” ) 1 ; la llamada a la función de biblioteca estándarprintfcorresponde a la acción semántica de la regla de producción B => b, que en este caso significa: Cuando el símbolo no-terminal ‘B’ derive en el símbolo terminal ‘b’, imprimir en salida estándar el carácter ‘b’. 3.5.2 Analizador Léxico El analizador léxico o lexicográfico que realiza InverSOODA se concibe como un módulo de software que realiza ordenadamente los siguientes pasos: 1. Lee de manera secuencia1 como un flujo de caracteres de texto el programa fuente en lenguaje C++. 2. Analiza caracter por caracter la cadena de entrada y construye subcadenas con significado llamadas muestras o tokens. 3. Alimenta a otro módulo de software denominado analizador sintáctico con dichas muestras. Las muestras se obtienen de acuerdo a reglas que definen el contenido de las muestras. AI contenido de las muestras se le conoce como lexema. Entonces, ¿qué se requiere para conshuir el analizador léxico?. Se debe definir el conjunto finito de muestras y describir qué cadenas forman las muestras. Además, la implementación debe cumplir los siguientes puntos: . 9 9 1 El reconocimiento de las cadenas correspondientes a las muestras La entrega de las muestras reconocidas. El regreso del valor o lexema de las muestras. Proveer una forma de resolver ambigüedades. La asignación de atributos de la muestra. 60 CAPÍTULO 3: E L MODELO CONCEPTUAd DEL SISTEMA LOS ANALIZADORES DE CODGO F UENTE Con la herramienta ANTLR los requisitos anteriores cabalmente al igual que con muchas otras automáticas de generación de analizadores. Respecto a dichas con ANTLR es que produce clases en lenguaje C++ o utiliza un objeto denominado lexer generado con de código en C++. Cabe mencionar que el analizador Béxico de InverSOODA reconoce muestras para un vocabulario parcial del lenguaje Cb+. I En la Tabla 3.1 se enlistan las muestras y los correspondientes lexemas que permiten reconocer las muestras léxicas d interés para un proceso de ingeniería inversa con la herramienta InverSOODA: I Muestra o token Palabras reservadas Lexema int, char, bool, float, double, void, long, signed, unsigned, short, if, else, while, class, StruCt, union, private, protected, Enseguida se muestran una serie de ilustraciones con' la representación de las reglas que permiten al analizador léxico reconocer las muestras listadas en la Tabla 3.1, CAPITULO 3: EL MODELO C ONCEPTUAL DEL SISTEMA La Figura 3.1 I muestra el autómata que define la regla para reconocer las palabras reservadas de C++ de interés. Se reconocen las palabras reservadas que definen tipos enteros, de punto flotante, booleanos y sin tipo; cláusulas de selección del tipo i f / else; repetición del tipo while;y, palabras reservadas clave para definir tipos de datos abstractos: class, struct y union, con las palabras reservadas que definen alcance: public, private, y protected. ini Figura 3.1 1 Autómata reconocedor de palabras reservadas 62 CAPiTULO 3: EL MODELO CONCEPTUAL DEL S IS TEMA LOS ANALIZADORES DE CODIGO FUENTE Los caracteres en blanco se reconocen con el autómata desplegado en la Figura 3.12. El interés en reconocer caracteres en blanco tiene la misma finalidad que la de un compilador de C++, discriminarlos. Caracteres en blanco \t I ' \n \r Figura 3.12 Autómata reconocedor de caracteres en blanco. Por su parte, tanto la Figura 3.13 como la Figura 3.14, ilustran los autómatas que reconocen los comentarios clásicos de C++. La finalidad de reconocer comentarios es la de discriminarlos. Sin embargo, en el trabajo de Biggerstaff (ver Sección 1.1.2 del capítulo 1), el tratamiento sofisticado de comentarios en procesos de recuperación de diseños puede jugar un papel interesante. Desgraciadamente, no está dentro del alcance de este trabajo, investigar más a fondo la importancia de los comentarios en la recuperación de diseños que tengan que ver con el diagrama de clases o del diseño detallado. E Comentarios de cualquier otro carácter menos \n cualquier otro caracter menos \n Figura 3.13 Autómata reconocedor de comentarios del tipo doble - diagonal 63 ' CAPiTULO 3: 'I E L MODELO CONCEPTUAL DEL SISTEMA ,I Figura 3.14 Autómata reconocedor de comentarios del tipo diagbnal - estrella. I1 La Figura 3.15 muestra un conjunto de caracteres simples reconocidos con los autómatas de la misma figura. ( ) Paréntesis izquierdo Parbniesis derecho ( ) Dichos caracteres simples se utilizan cotidianamente en la codificación de programas en C++, aunque distan de ser la totalidad de caracteres simples que pueden considerarse como muestras. Para el objetivo de este proyecto sólo fueron los necesarios. * - Figura 3.15 Autómata reconocedor de diversos caracteres simples. 64 CAPiTULO 3: EL MODELO CONCEPTUAL DEL S ISTEMA LOS ANALIZADORES DE CODIGO F UENTE ' I Caracteres de escape cualquier otro carácter menos \ Caracteres literales Figura 3.16 Autómata reconocedor de caracteres literales. Tanto caracteres literales como cadenas literales son englobados como muestras en el análisis léxico, ilustrados en las Figuras 3.16 y 3.17. Este tipo de muestras son un tanto más complicadas para el análisis léxico debido a que pueden contener caracteres que a su vez se consideran como caracteres simples. Caracteres de Caracteres de I \ cualouierotro carácter l. / / Figura 3.17 Autómata reconocedor de cadenas literales. La Figura 3.18 tiene ilustrado el autómata que reconoce las secuencias de escape. Estos caracteres especiales también se consideraron puesto que pueden verse como un subautómata de los autómatas de las Figuras 3.16 y 3.17 anteriores. 65 ~~~ CAPiTULO 3: ~~ ~ EL M ODELO CONCEPTUAL DEL SISTEMA de escape It 'I Figura 3.1 8 Autómata que reconoce caracteres de escape. I/ Para poder reconocer tanto identificadores como números enteros; es crucial identificar digitos. Entonces, se puede ver como un subautomata el dibujo de la Figura 3.19 al enfocarse tanto hacia el autómata de la Figura 3.20 como al autómata de la Figura 3.21. I/ 8 I1 6 4 I 2 O 11 1 3 5 I1 7 9 Figura 3.19 Autómata reconocedor de dígitos decimales. 66 I CAPiTULO 3: EL MODELO CONCEPTUAL DEL SISTEMA LOS ANALIZADORES DE CODIUO F UENTE Los autómatas de las Figuras 3.20 y 3.21 reconocen números enteros e identificadores respectivamente. El reconocimiento de identificadores es de especial relevancia para el proceso de ingeniería inversa, debido que normalmente un identificador representa el nombre de clases, de variables y de métodos o funciones. En la sección posterior se explica porque es especialmente importante el reconocimiento de identificadores durante un proceso de recuperación de diseiios. Numero entero +-?t Digito Digito Figura 3.20. Autómata reconocedor de números enteros. Letra Digito I Identificador II Digito ~ Figura 3.21 Autómata reconocedor de identificadores. 3.5.3 Analizador sintáctico y semántico Una vez que las muestras son aceptadas o reconocidas por el analizador léxico (ver Sección 3.5.2) el segundo paso en la recuperación del diseño desde código fuente es entender la estmctura de las oraciones del lenguaje C++. El analizador sintáctico de InverSOODA verifica que las muestras obtenidas ppr el analizador se encuentren dentro de la estructura sintáctica del lenguaje C++ pero, además, realiza a la vez el análisis semántico que a la postre es la clave de la ingeniería inversa propuesta en este proyecto. 61 I! CAP¡TULO 3: E L MODELO CONCEPTUAL DEL SISTEMA 3.5.3.1 Análisis sintáctico del lenguaje de programación C++ I1 I El lenguaje C++ ha sido reconocido por la comunidad de desarrolladores como un lenguaje cuya gramática es extremadamente ambigua. Esto se traduce enlque el análisis sintáctico de la totalidad de este lenguaje sea una labor bastante compleja. Se necesitan aplicar métodos y estrategias de desambiguación para poder interpretar o compilar toda la expresividad del lenguaje. Constantemente están siendo mejorados los compiladores de C++ para poder analizar eficazmente el código y crear imágenes 'kjecutables o bibliotecas de clases. Aún a la fecha, los compiladores comerciales o libres como Microsoft Visual C++ o Borland C++ para sistemas operativos Windows, Metrowerks de Macintosh o GCC para sistemas Linux varían en el resultado directo que emiten después de un proceso de análisis de código fuente en C++. I1 1 it I1 I/ El hecho de construir un analizador sintáctico para todo el espectro de producciones gramaticales es de una complejidad inalcanzable para un proyecto de las dimensiones de este trabajo. Sin embargo, se pudo identificar un subconjunto de la gramática lo suficientemente completo para traducir oraciones de C++ a diagramas de clases en C++. I/ j I) 3.5.3.2 Uso del ANTLR en la construcción del analizador sintácfico de C++ I/ I .I < La herramienta ANTLR juega un papel primordial en la construcción del analizador sintáctico de InverSOODA, pero también en el análisis semántico. El ANTLR tiene entre otras muchas curiosidades, mecanismos de desambiguación I) llamados predicados sintácticos con los que fue posible evitar la creación de árboles de derivación no deseados. Además, la simpleza y naturalidad con la que se puede definir enjun archivo de texto la especificación gramatical del lenguaje (ver Sección 3.5.1), permite ajustar casi a la perfección los esquemas de traducción STDS. ANTLR permite utilizar acciones semánticas intercaladas en las producciones gramaticales que en InverSOODA sirven para controlar la traducción. t 111 3.5.3.3 Esquema de traducción aplicado en la recuperación de diseños (I En esta sección se incluye la Tabla 3.2. que lista en la primera columna las producciones gramaticales apegadas ai esquema de traducción. En la segunda ,tcolumna aparecen las acciones seinánticas correspondientes a cada producción gramatical. /I Las producciones gramaticales están ordenadas de acuerdo a la clasificación en el Apéndice A en se trata de varias secciones que engloban las reglas gramaticales de C++ conforme al tipo de oración que generan. Para algunas producliones gramaticales no fue necesario asociarles acción semántica alguna, pero existen :lpara poder seguir la secuencia de derivación. Cabe mencionar que es de especial importancia el previo reconocimiento léxico de identificadores puesto que durante el analisis semántico éstos normalmente son candidatos a representarse como la figura clase dentro del diagrama de clases recuperado. 68 - .- LOS ANALIZADORES DE CÓDIGOFUENTE CAPiTULO 3: EL MODELO CONCEPTUAL DEL SISTEMA i . 1 ....... . . . . . . . .................................................................................... Esquema de traducción entre el lenguaje C++ y diagramas de clases del UML sección 1. Programa -- i -_ i i rAc,;ones semánticas .__.___-, 1.la. Recorrer un vector con las agregaciones encontradas, crear las figuras agregacion y asociarlas con las clases correspondientes. ~cZi&nT~aZiEiil 1.1 UnidadDeTraduccion => declaracion EOF 1 ~ 1 11 ~ j 1.1b. Recorrer un vector con las herencias encontradas, crear las figuras herencia, y asociarlas con las clases correspondientes. 1 I Sección II. Expresiones i ' 1 Producción gramatical 11.1 exprld => idNoCualificado -.__ 11.2 idNoCualificado => ldentificador r -..-~--~-..__._I-I ---[Acciones __._.-.-_I_. ----.---.--___I__ declSimple => secDeclEsp IistalnicDecla ; => secDeclEsp ; ........ deciSimple =7 ; .... .................................................... I If3'secDeclEsp => especDecl I IV.4 especDecl => especTipo - ... ,I" 1 "' .,4_..- .i ................................. especSimpleTipo => tipoFlotante .................................... , ......... , ................ esDecSimDleTiDo => tipoEntero "'especSimpleTipo => boo1 - .......... .-.... ..... -. . - . - . - ~- . .. . - - ... .......... ....................... ...... a Verificar si el nombre del tipo ... ........... 1 corresponde a una agregación. .... . . . . . . . . . . . . . . . . . . . . . .~. ....................................... . ................................ - i.-. .,. .............................................. ' ..................................................... ... - I especTipo => especElabTipo - ............ "' r--Ir--I ........................................................ ... ...... I IV.6 especSimpleTipo => nombreTipo I¡ -__I---_-.._ - f- I -r--r-- . . . . . .especTipo . . . . . . . . . . . . . . . . .=> . . . . .especSimpleTipo ................ .............. I ~ .... .. rN.5 especTipo => especClFe ___ [ ~. - => IistalnicDecla ; declSimple ...................... .''' - __ bcciones semánticas. - Froáucción gramatical ... __ . l.lV:l declaracion => declSimple [ I___ 2.2 Almacenar el nombre del ldentificador como nombre temporal Sección IV. Declaraciones r'-declSimple semánticas _ l _ _ ~ _ _ _ . _ . . . ....... -. ....... ........ /'4:6b'Almacenar boo1 como tipo temporal .-~ ........................ ~...................... .~ . Tabla 3.2 Esquema de traducción entre e l lenguaje C++ y diagramas de clases del UML 69 : ~1 ~ CAPiTULO 3: EL MODELOCONCEPTUAL DEL SISTEMA I1 I/ .... 7- Esquema de traducción entre el lenguaje C++ y diagramas de clases del .UML (continuación...) .......... . . . . . . . . . . . . . . . L. . . . . . . . ................. Producción gramatical .................................................................... i"IV.7 especElabTipo => claveclase ....................... ., "'['Acciones semánticas I-'-- . . . . . ,'4BAimac.e .... . . . . . . 1 iV.8 nombreTipo => Identificador ...................................................... I IV.9 especFunc => inline I ...........I. ............................ ................................................................ .-____I__ ; V.3 declarador => exprld ( ) I "j -. . -, -- declarador => exorld , . . . . . . . . . . .~ . . . . . . . . . . . . /'''''''.' ........................................... . V.2 decllnic => declarador . , . - r-I ._ . : j ..... .-~...> ..... '1 Secci6n V. Declaradores . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ... i....... i V.¡ IistalnicDecla => IistalnicDecla, decllnic ...................... .. .... nar el nom'bre del ldentificador como el tipo i especFunc => virtual ~... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ; - ........... - . ~ ~ . .. . . . .................. ._II.._._.__..._____._ - .................. . . . . . . . ............ ... ............... . : - - ! /I i'.'metodoVirtual => secDeclMetodoVirtual i:.' ... ...................................... .~. ~ , .......... r - ..~ ._ . . . . . . . . ", ~~8cecDeclEspMetodoVirtual => virtual -11 -especTipoRetFunc inline ........................................................................................................... V.9 secDeclEspMetodoSimple => I/ especTipoRetFunc inline --V.10 secDeclEspFunc => especTipoRetFunc -" -especfunc ._..________.._-._____---....I_.__-____.secDeclEspFunc => especFunc esDecTiooRetFunc I r- ~- r- .I..........-- I v.1. .I. .especTipoRetFunc => especSimpleTipo . . . . . . . . . . . . . . . . . . . . . . . . . . __ ....... I---- especTipoRetFunc => void .............. , ................. ...,. .. r ........ ........................................... I---' .... - L ... ..,.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . - ii . . . . I/ ................................... Tabla 3.2 Esquema de traducción entre e l lenguaje C++ y diagramas de clases del UML (continuación.. .) 4 70 CAPiTULO 3: -__ ..- .-....... j sección Ir----- 1 ~ LOS ANALIZADORES DE CODIGOF UENTE EL MODELO CONCEPTUAL DEL SISTEMA --. - --. .. - -. - ..- - ............. Esquema de traducción entre el lenguaje C++ y diagramas de clases del UML (continuación...) ~ Via Clases __ 1 Acciones semánticas ... .-.- ...... . , Producción gramatical _______.I" Vla.1 especclase => cabeceraclase { especMiembro ] .. i 6a.la Crear la figura clase en base a la 1 clase temporal y los valores de esta ultima . I I 1 6a.l b Limpiar todo almacenamiento de I atributos temporales .............................. ................................................... rVra2-cabeceraClase => claveClase ldentificador ........... .cabeceraclase => claveClase ldentificador clausulaüase 1 i .................................. l'Via32aveciase => class [ c l a v e c l a s e => struct 1I 1 ~-... i 6a.2a Almacenar el nombre del ldentificador como el nombre de la clase ! __ ............................... 6a.2b Almacenar el nombre del ldentificador como el nombre de la clase ! ! I 6 a . 2 ~Verificar si el nombre del tipo corresponde con una herencia ................ k.a:3EFeZuna figura clase temporal ,I i'.' ____ . i... I I ~ ~ r declaracionMiembro => ; ................................................... / ~ ¡ ~ ~ s t a D e c l M i e m b=> r o declaradorMiembro . . . . i r-,.. ...................... . . . .=> . . . . .declarador ... , . . . . . . . . . . I I- ... - -........................... - ..,. ......... ................................. Tabla 3.2 Esquema de traducción entre el lenguaje C++ y diagramas de clases del UML (continuación ...) 71 ~ j i ¡ ~ I ! j 1 j : - ........................ -.' i ..................................... ................. ListaDeclMiembro => IistaDeclMiernbro , lVla.7 . . . . . declaradorMiembro ....... .- j I - -- ~ 1 declaradorMiembro ............................. ~ i claveclase ____ ......................................... => union ................................. Vla.4 especMiembro => declaracionMiembro especMiembro => declaracionMiembro esDecMiembro I . . . . . . esDecMiembro => esoecAcceso : I .... ~...................................... ~ _ _....................... _ especMiembro =>.especAcceso : . I especMiembro -- ................... ., .. ., ........ ................................... . ~ .,. . . . Vla.5 declaracionMiembro => : 6a.5a Establecer los métodos de la clase defFuncMiembro ; temporal en base a los demás datos temporales __ ....................... ...... ______.___ ..,...... .............. declaracionMiembro => 6a.5b Establecer los métodos de la clase defFuncMiembro temporal en base a los demás datos temporales i "i declaracionMiembro => 6 a . k Establecer los atributos de la clase especSimpleTipo temporal en base a los demás datos temporales 1 IistaDeclMiembro ; I 1 t . 1 , CAPiTULO 3: EL M ODELO CONCEPTUAL DEL SISTEMA I/ Esquema d e traducción entre el lenguaje:C++ y diagramas d_e clases del UML (continuac'ión ...) .......................... ............................. ................. I ! .. j _ ~ . Sección Vlb. Clases Derivadas .______ . .. ._"____..__I_ __-__ _ . Acciones semánticas "' Producción -gramatical .__. " __._- .~ . . Vlb.1 clausuiaBase => : especAcceso nombreTipo _ ....................... ..................................... ... . . . . . . . . . . . . . . . .,......... 6b.2a Almacenar private como el acceso : Vlb.2 especAcceso => private temporal ........................ .......... ......... especAcceso => public 6b.2b Almacenar public p r n o el acceso temporal . ..._......__._._I___-.I-.-. 6 b . 2 ~Almacenar protected como el a c c e s o : especAcceso => protected .... ._l__ll_-_ ') _--.I_-_ ____.-- temporal II ~ I _- 1 i ~ I i Sección VII. Reglas de producción para tipos de datos tipo temporal t Almacenar combinación de entero signo como el tipo temporal unsigned short int como tipoEnteroConSigno => (todas las combinaciones del lado derecho anterior) VIL4 tipoEnteroSinSigno => unsigned short int ~ - - ..... r-~tipoEnteroSinSigno I ~ . i1 ........................................... 1 _ I _ _ _ r s a r a c t e r => signed char i _.____._____.__r.l-_____.. j tipoCaracter.=> char <_ ~ ................................... . . . . I . ~ - i' ............. .. .- -~ _ unsigned long int como el tipo temporal .. . 7.4~ Almacenar combinacióp de entero sin signo como el tipo temporal ............................... tipoEnteroSinSigno => (todas las combinaciones del lado derecho anterior) ........................ ................. V11.5 tipocaracter => unsigned char :, ~ ........... L ! ji . ..................................................... I 7.5a Almacenar unsigned char como el 1 tipo temporal r I1 ! ~ --I 7.5b Almacenar signed char'como el tipo temporal i 1 7 . 5 Almacenar ~ char como ei,tipo temporal I ......................... .................................... _ _ I ~ -t . -. . 4 Tabla 3.2 Esquema de traducción entre el lenguaje C++ y diagramas de clases del UML (continuación ...) 72 , ~ CAPiTULO 3: LOS A N A L I Z A D O E S DE CODICO FUENTE EL M ODEL O CONCEPTUAL DEL SISTEMA De manera conceptual un ejemplo sencillo de traducción bajo el esquema de la Tabla 3.2 se realizaría así: Código fuente Diagrama de clases UML Figura 3.22 Traducción entre una clase en código fuente hacia una figura. UoidadDeTraduccion 1 1 6a.la 6a.lb c Dedaraci6o dedSimple 1 1 1 6b.2b cabeceraclase e~pecDecl 1 espechniembro j 6a.5b I eSpeCTipo 1 especc1ase- [ w 1 1 I secDedE~pec 1 defFUnCMiembiO 1 rnetcdoSimple secDelEspMelcdoSirnple declaradorMiernbr IipoEnIer~ 1 1 Iip~EnIeroC~nSign~ 7.3n in, 1 1 1 exprld declarad tipoEnIero idNoCualificado exprld 2.2 rfi 1 1 1 1 2.2 1 1 2 BspecTipoRetFunc declarado especSimpleTipo Idenüficador tipocaracter char ( J, - Figura 3.23 Ejemplo de árbol sintáctico de derivación con acciones semánticas 73 _CAPiTULO 3: E L MODELO CONCEPTUAL DEL SISTEMA En la Figura 3.23 de la página anterior, las acciones semánticas se aprecian con la numeración descrita en la Tabla 3.2, en letra negrita, y al lado de la’producción gramatical que las produjo. De esta manera, si se graficara el orden de aparición de las acciones semánticas y la traducción que realizan se apreciase algo como lo ‘mostrado en la Figura 3.24. I I I I I 6a.3 6b.2b 7.311 2.2 6a.5~ 7.5~ 1 I I I 2.2 6aSb 6a.la 6a.la , Se traduce a Crear una clase temporal O01 Se traduce a o n e Almacenar public temporalmente o Almacenar int temporalmente Se traduce a u n Se traduce a ,on> Se traduce a Almacenar “x” temporalmente Establecer un nuevo atributo en clase temporal Se traduce a Almacenar char temporalmente Se traduce a Almacenar “f’ temporalmente Se traduce a 10Se traduce a 10- e Establecer u n nuevo o método en clase temporal Crear la figura Clase con el identificador que sigue a la palabra class y con los valores de la clase temporal I e +x:’T + f(): char I Figura 3.24 Orden de ejecución de acciones semánticas y sus correspondientes efectos en la traducción. 74 . - . . .. . . - -. . ... .. . _.~. ~~ y’*‘1.. CAP~TULO 3: EL MODELO CONCEPTUAL DEL SISTEMA INTERACCiON CON INVEFdlDVi 3.6 Interacción con InverDDVi I El presente proyecto plantea que es factible la recuperación del diseño detallado de métodos de clases. Retomando algunas ideas de la Secciones 2.3.2 y 2.4 del segundo capítulo, se tiene que InverDDVi es la herramienta con la que se auxilia InverSOODA para recuperar el diseño detallado. ¿Cuándo se presenta la interacción entre InverSOODA e InverDDVi?. Una vez que se realiza el proceso de ingenieria inversa para obtener el diagrama de clases, se puede proceder a llamar InverDDVi individualmente para cada método de cada clase (ver Figura 3.25) I Proceso de ingenieria inversa para obtener el diagrama de clases del i << produce >> Diagrama de clases ........., ........ hlormac¡un sobre especifico+ la clase que los ~ Sintáctico I Semántico i:::: 1- I .y*. -..-..,. e-, - El usuario d e la aplicación tiene la responsabilidad de llamar a InverDDVi desde la interíaz de InverSooda para obtener el diagrama de Warnier de cada método. :”.- Despliegue independiente del diseno detallado del método de’clase al que se le aplique ingenieria inversa con DOVi. t ~~ Figura 3.25 Interacción de la herramienta InverDDVi en el proceso de recuperación de diseño detallado de métodos de clases. InverDDVi toma el nombre del método del que se requiere obtener el diseño detallado para iniciar su propio proceso de ingeniería inversa. Los nombres de los métodos específicos a una clase están almacenados en un vector de cadenas o strings en dicha clase. La interfaz gráfica de usuario de InverSOODA permite realizar la llamada al módulo InverDDVi. Los detalles del cómo se realiza esta llamada y muchos otros aspectos de implementación de InverSOODA se encuentran en el siguiente capítulo de este documento. I 75 CAPiTULO 3: EL MODELO CONCEPTUAL DEL SISTEMA 3.7 Referencias [Ant031 ANTLR. ANother Tool forLanguage Recognition. htto:l/antlr.orql I 9 Febrero de 2003. [Dan021 Daniels John. Modeling with a Sense ofpurpose. (EU.: IEEE S o h a r e , EnerilFebrero de 2002) pp. 8-10 [Gam951 Gamma Erich et al. Design Patterns-Elements of Reusable Object Orie+ed Software, (E.U.: AddisonWesley-Longrnan.1995). [ParüO] Parra Rarnirez. Isaac A. Modelado Visual Orientado a Objetos. (Tesis de Mabstria, CENIDET. Cuernavaca. Morelos. Mexico. Diciembre del 2000) pp. 5.8, 5.4. [Ctl91] Slroustrup Eijarne. The C++ programming language. Company, Segunda Edición, 1991) pp. 614-616. I/ ll (New Jersey, EU!: Addison-Wesley Publishing '! 76 Capítulo 4 . "Sino saben programar, ZEnionces qué saben?" R. A. Pazos 4.1 4.2 4.3 4.4 4.5 Introducción Manejo de la interfaz gráfica de usuario Implementación de los analizadores de código fuente Pruebas Referencias CAPiTULO 4: DESARROLLO Y PRUEBAS DE L A HERRAMIENTA INTRODUCC~ON 4.1 Introducción El presente capítulo da a conocer al lector un resumen del desarrollo de la herramienta denominada InverSOODA y algunas de las pruebas aplicadas a ésta. La descripción del desarrollo de la herramienta retoma algunas ideas expuestas en el capitulo anterior, principalmente cuestiones sobre la construcción de diagramas a partir del análisis de código fuente. También presenta de manera breve cómo es la interacción de la interfaz gráfica de la herramienta con el usuario. Además, se presentan dos casos de estudio a manera de pruebas. De estas pruebas se desprende un análisis de los resultados obtenidos para constatar la validez de la hipótesls que sostiene el presente trabajo; análisis que se incluye en el siguiente capítulo. 4.2 Manejo de la interfaz gráfica de usuario La interfaz gráfica de usuario (GUI por sus siglas en inglés) de InverSOODA es parecida de su antecesor SOODA, excepto por algunos cambios en las barras de herramientas y de modelado: un nuevo botón para la primera, como se muestra en la Figura 4.1: II Barra de'modelado de SOODA Barra de herramientas de SOODA I' El Figura 4.1 Cambios en las barras de modelado y de herramientas de SOODA Nótese que, de acuerdo a.la figura anterior, aparece un nuevo icono en la barra de herramientas de InverSOODA: el icono en forma de flecha que parece girar apuntando hacia la izquierda. Este es el icono a través del cual se llaman los mecanismos de ingeniería inversa. I/ Los demás elementos de la GUI tienen la misma apariencia y funcionamiento que en SOODA, es decir, la interfaz que dirige el proceso de ingeniería directa aparece idéntica para el usuario final. En la Figura 4.2 de la página siguiente se ilustra la interfaz gráfica de . usuario de InverSOODA. 79 C A P h U L O 4: DESARROLLO Y PRUEBAS DE L A HERRAMIENTA 11 Figura 4.2 Interfaz gráfica de usuario de InverSOODA. I1 Como se puede apreciar en la figura anterior, las barras de iconos aparecen justo abajo del menú clásico de toda aplicación para Windows de Microsof?, sinqque esto signifique que siempre estarán ahí; ambas son del tipo Jotante y pueden moverse de posición y aparecer en cualquier lugar de la pantalla, a manera de ventanas hijas. I 4.2.1 Activacih de la ingeniería inversa para recuperar diagramas de clases desde la GUI Recordando ideas de !a sección 3.4.4.1, se tiene que la construcción de giagramas de clases durante procesos de ingeniería directa se dirige por medio de la barra de modelado en intervalos asíncronos de tiempo, mientras que la ingeniería inversa es un proceso síncrono. ¿En que parte de la GUI de inicia el proceso de ingeniería inversa?. En el II nuevo icono que aparece en la barra de herramientas. N ¿Cuándo es posible disparar los procesos de ingeniería inversa?. En cualquier momento que el usuario lo desee, sólo debe tener cuidabo de guardar !os diagramas con los que estuviera trabajando previo a! llamado de la recuperación de diseños. ,PU,same, CAPiTULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA MANEJO DE CUI Una vez que se pulsó el botón de la barra de herramientas para iniciar un proceso de ingeniería inversa aparecerá un cuadro de diálogo preguntando si se quiere iniciar un nuevo proceso de ingenieria inversa, como se muestra en la Figura 4.3. Figura 4.3 Cuadro de diálogo que pregunta si se inicia otro proceso de ingeniería inversa. 11 La intención de este diálogo es la de prevenir al usuario final de que está por comenzar un proceso de ingeniería inversa y es probable perder los datos de diagramas en uso. Si el usuario pulsa el botón del diálogo etiquetado con un Sí, entonces InverSOODA procederá con un proceso de ingeniería cuyo resultado borrará el estado volátil de cualquier diagrama que haya estado activo justo antes. Caso contrario, InverSOODA continúa con el proceso de recuperación de diseños sin destruir el diagrama anterior'. Seguido al cuadro de diálogo que aparece en la Figura 4.3, la herramienta presenta al usuario otra ventana especial, un cuadro de dialogo especializado para seleccionar archivos, mejor conocido como un File Dialog, como se indica en la Figura 4.4 de la siguiente página. ' En versiones posteriores de la herramicnia se propone mejorar esla interacción con algún mecanismo que permla cancelar l a accibn misma de iniciar procesos de ingenieria invcrsa. 81 CAPITULO 4 DESARROLLO Y PRUEBAS DE LA H ERRAMIENTA I1 ,I ! Figura 4.4Cuadro de diálogo para seleccionar el archivo que contiene e1 código fuente en C++ sobre el cual se aplicará la recuperación de diseño. Una vez que se selecciona el archivo (uno sólo), entonces comienza el proceso de análisis del código fuente contenido en dicho archivo. Si el código fuente se apega a las restricciones mencionadas en la Sección 1.6 del primer capítulo de este documento, entonces aparecerá el mensaje ilustrado en la Figura 4.5 de la siguiente página y posteriormente el diagrama de clases del UML que corresponde al diseño del código fuente recién analizado. Como se puede obse&ar en las últimas figuras, la interacción del usuario con la GUI para resolver la recuperación de diseños es bastante simple. La post-interpretación de aspectos semánticos de los diagramas de clases I/ del UML recuperados queda fuera del alcance de InverSOODA. ,I ' .. , Cuando se obtiene con éxito el diagrama de clases del UML, entonces termina el proceso de ingeniería inversa, y el usuario está facultado para manipular a su libre albedrío el diagrama. Por ejemplo, puede manipularlo gráficamente para acomodar las figuras, acceder a los datos de'las clases y modificarlos, agregar nuevas c'lases y relaciones. En suma, puede iniciar un proceso de ingeniería directa como con cualqdier otro diagrama de la herramienta. ¿Qué hay del diseño detallado de las clases recuperadas?. El proceso de ingeniería inversa para recuperar el diseño detallado de métodos se expliba en la siguiente ,I sección. CAPiTULO4: DESARROLLO Y PRUEBAS DE LA H ERRAMIENTA M ANEJO DE GUI Figura 4.5 Cuadro de diálogo:que indica al usuario la recuperación con éxito de un diseño desde código fuente. 4.2.2 Activación de la ingeniería inversa para recuperar el diseño detallado de métodos desde la GUI Actualmente, InverSOODA trabaja de manera separada respecto a InverDDVi, aunque se propone unir la funcionalidad de estas herramientas a futuro. InverDDVi obtiene el diseño detallado de métodos analizando un archivo a la vez. La limitación es que, para que ambas herramientas recuperen en bolaboración el diseño detallado de métodos pertinente, se necesita tener en archivos separados la implementación de los métodos, archivos almacenados preferentemente con extensión c o cpp. De tal suerte, sólo es posible recuperar el diseño detallado de métodos, de manera apropiada, en los casos que se apeguen a la limitación recién mencionada. Afortunadamente, InverDDVi no presenta problemas para analizar implementaciones de funciones miembro al estilo C++, tomando en cuenta que InverDDVi fue diseñada para analizar código en lengua$ C. Esto se debe a que el esquema de análisis de código de InverDDVi busca instrucciones secuenciales, repetitivas o de selección adentro de CAP~TULO 4: DESARROLLO Y PRUEBAS DE LA H ERRAMIENTA funciones. Lo anterior implica que los procesos de análisis de InverDDVi busquen i ávidamente nombres de funciones seguidas de paréntesis. Construcciones del tipo: void Ciertaclase i :: funcionl O / / lo que sea . . . I no afectan al análisis posterior que se realiza adentro del bloque 'hefinido dentro de la función identificada como tal. InverDDVi se ejecutará como una aplicación aparte y desplegará su clásica interfaz con el diagrama de Wamier correspondiente al diseño detallado del método que corresponda al llamado. La Figura 4.6 muestra un ejemplo de diseño detallado obtenido para un método de clase cuyo diseño 'fue recuperado, por supuesto, previamente desde InverSOODA. . . .n . . r r . m. . . . F 'enana "8 >IS181&lQlCAl5 1 PlY?lOl <I1 l , 1 ,# ; Ed>* yer ~1@1@1@(1 gI -., sp w u e I {I, *{ 1 2 s d l ~ ~ @ & ~ ' & ~ ~ .! - . "! .. '. -x :*r, .. dBI A li =O- 4" =*- Figura 4.6 Ejemplo de un diagrama de Wamier que corresponde al diseñc$detallado de un método de clase. De acuerdo con la figura anterior, se observan los siguientes elementos dentro del diagrama de Wamier obtenido por InverDDVi: el segundo triángulo 1 representa una llamada a procedimiento de nombre fl, acotando otros elementos con la primera llave; enseguida, se encuentra un ciclo controlado por la variable i; después, se representa un 84 CAPiTULO 4: D ESARROLLO Y PRUEBAS DE LA MANEJO DE GUI HERRAMIENTA estatuto condicional que a su vez se encuentra dentro del acotamiento de la llave del ciclo, la condición evalúa la expresión f < 100; y, finalmente, una condición negada. El código correspondiente al diagrama desplegado en la figura anterior se encuentra almacenado en un archivo de nombre A.cpp y es el siguiente: #include "a.h" int A : : El O ( int i; while ( i ) i 1 I I1 if ( i < io0 ) printf ( "Actual valor % d " , i else break; ) ; Si se observa el trozo de código anterior, se puede notar que la función no es de tipo global (al estilo C), sino más bien una implementación de un método llamadofl, que es miembro de la clase denominada A . Queda en el aire la pregunta obligada para esta sección: ¿Cómo accionar desde InverSOODA la recuperación del diseño detallado de un método de una clase en particular?. La Figura 4.7 ilustra gráficamente esta cuestión seguida de una breve explicación en la página siguiente. J I' Figura 4.7 Instantánea de la'interfaz utilizada cuando se acciona la recuperación del diseño detallado de un método en particular. 85 CAPiTULO 4: D ESARROLLO Y PRUEBAS DE LA HERRAMIENTA I1 8) Una vez que se recuperó un diagrama de clases es factible la fecuperación del diseño detallado de métodos de clases siempre y cuando alguna de las clases del diagrama recién recuperado contenga métodos. Se selecciona el primer icono de la barra de modelado (ver figura 4.l),la cual corresponde a la figura apuntador. Enseguida selselecciona la clase que contiene el método de interés pulsando el botón derecho del ratón.'hEntonces aparecerá un cuadro de diálogo con varias pestañas. Se selecciona enseguida la pestaña etiquetada como métodos. En, la pestaña denominada métodos aparece una región que despliega un listado con los nombres de los métodos miembro.de la clase seleccionada! Se pulsa de nuevo el botón derecho del ratón posicionando antes el cursor sobre el método de interés. Acto seguido aparece un pequeño menú con las siguientes opciones: . 9 1 1 Insertar Borrar Modificar Diseño Es de especial interés la opción del menú anterior llamada Diseño; puesto que al pulsar el botón derecho del ratón se activa la llamada a InverDDVi. Entoncds el usuario estará en posibilidad de usar el InverDDVi para recuperar el diseño detallado del método que seleccionó desde InverSOODA. I1 ,I ,. ,I 4.3 Implementación de los analizadores de código fuente II Para entender más a fondo la descripción de la implementación deilos analizadores se recomienda que el lector haya repasado las secciones 3.4.4,3.5.1, 3.5.28~3.5.3 en donde se desarrollan los siguientes temas: o 3.4.4 Uso del patrón de diseño Builder como base para construir el diagrama de clases o 3.5.1 Creación de analizadores de código con ANTLR 1 I o 3.5.2 Analizador léxico I o 3.5.3 Analizador sintáctico y semántico 4.3.1 Implementación del analizador léxico El analizador léxico se apega a la definición de muestras listadas en la Tabla 3.1 y conceptualmente a los autómatas ilustrados en las figuras numeradas del 3.11 al 3.21. Además, se implementa en un archivo de especificación gramatical de acuerdo a las reglas mencionadas en la Sección 3.5.1. Los detalles de implementación que no, se trataron en ese capítulo se enuncian en los siguientes párrafos. En el archivo de especificación gramatical del analizador léxico se especificaron varias opciones especiales que indican al ANTLR como generar dicho analizador. Entre estas opciones se tiene: 86 CAPITULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA I M ~ L E M E N T A C I ~DE N ANALIZADORES o La sección options general:,' options { mangleLiteralPrefix = "TK-" ; language= "Cpp"; 1 10 LO anterior indica al ANTLR que concatene el prefijo TK- a cada muestra, Y que el Lenguaje en el que se genere e\ analizador léxico sea C++. o La definición de la clase ,TinyCLexery sus inmediatas opciones: class TinyCLexer extends Lexer; options { k=2; exportVocab=TinyC; charvocabularx = '\3'..'\377'; 1 4 TinyCLexer es el nombre de la clase generada por ANTLR a partir de la clase Lexer. Es la clase que define en su implementación el analizador léxico2. La linea k=2 significa que se utiliza un;lookahead de dos caracteres. export Vocab=TinyC significa que el analizador léxico exporta un vocabulario o conjunto de tokens denominado TilryC hacia cualquier analizador sintáctico generado también con ANTLR. Finalmente, charVocabulary= 'I3 '.. '1377' define el rango de caracteres que TinyCLexer puede identificar, para este caso,,'sedefinió el rango de los caracteres ASCII. o La sección tokens: tokens , I "int"; "char"; "bool"; '"float't;lldoublev; "voidt!; t!longu; nwsignedrr "unsigned"; ushoS-t!. ! ) i f,! #"else"; . "while"; "class"; "struct"; "union"; "private!; "protected"; "public"; "inline"; "virtual"; 1 El ANTLR permite, definir en una sección especial denominada tokens aquellas muestras que explícitamente se definen sin utilizar derivaciones. o Regias protegidas y no protegidas: a) Protegidas. Reglas que no interesan al analizador sintáctico. I protected DIGIT : *'0'..'9' ' El lipa de analizadores que genera el ANTLR son LL ( k ). 87 CAPfTULO 4: DESARROLLO Y PRUEBAS DE LA HERRAM~ENTA b) No protegidas. Reglas que se entregan al analizador sintáctico una vez reconocidas. ID : ( ' ~ ' . . ' Z ' ~ ' A ' . . ' Z ' ~ '(- ~' )a ' , . ~ z ~ ~ ' ~ ~ . . ~ z ~ ~ ~ - ' ~ ' o ' . , ii Nótese que la regla ID se define en un forma parecida a las expresiones regulares; ésta es una opción alternativa que provee ANTLR para definir derivaciones. Cabe mencionar que toda especificación de muestras debe iniciar con uda letra mayúscula. 4.3.2 Implementación del analizador sintáctico I1 'I La Tabla 3.2 del capítulo anterior define las reglas gramaticales que se especificaron en un archivo para ANTLR de acuerdo a las reglas mencionadas en la Seccion 3.5.1. A partir de dicha especificación se generó el analizador sintáctico. Los detalles de la implementación dentro del archivo de especificación gramatical se enlistan a continuación: O La sección header, que sirve para agregar código fuente de preprocesador y variables o funciones globales , I/ header ( 1 #include #include #include #include <iostream.h> "StdAfx.h" "Clase.h" "1nverSoodaDiagrarnaBuilder.h" .I ,I Concretamente en el código anterior se añadieron los archivos i0stream.h para manejo de salida estándar, 3dAfx.h para manejo de objetos básicos MFC, C1ase.h que contiene la definición para objetos con la figura clase. Finalmente, InverSoodaDiagramaBuilder.h,que es la definición del objeto/I que dirige la construcción síncrona de un diagrama de clases. O La sección options general: options { rnangleLiteralPrefix = "TK-" ; language="Cpp" ; ) Lo anterior indica al ANTLR que concatene el prefijo TK- a +da muestra, y que el lenguaje en el que se genere el analizador léxico sea Ctt-. O La definición de la clase TinyCPPParser y sus inmediatas opciones: 88 .... .,*“~.t?p> :.. .I( CAPÍTULO 4: DESARROLLO Y PRUEBAS DE L A HERRAMIENTA .. I IMPLEMENTACIÓN DE ANALIZADORES c l a s s T i n y C P P P a r s e r extends P a r s e r ; options I I importVocab=TinyC; I) El analizador sintactico está definido dentro de una clase llamada TinyCPPParser. A su ,hez, dicha clase hereda funcionalidad de un clase más genérica llamada Purse;. La oración itnportVocub=TinyC indica al ANTLR que el analizador sintáctico utiiliza un conjunto de muestras definidos en el vocabulario TinyC. Dicho vocabulario se define previamente en el analizador léxico TinyCLexer (ver Sección 4.3.1). ‘1 o Sección de código: / / Seccion de codigo I public: CInverSoodaDiagramaBuilder* g e t B u i l d e r O ( r e t u r n b u i l d e r ; ) private : CInverSoodaDiagramaBuilder * b u i l d e r ; 1 Justo después de la sección options de la definiciGn de TinyCPPParser se agrega una sección especial delimitada solamente por un par de llaves que abren y cierran. Es la sección que indica al ANTLR que el código ahí encerrado es particular a la implementación del analizador. Específicamente, en la porción de código anterior se declara como privado dh apuntador a objetos Builder (ver Sección 3.4.4), que son los encargados de construir los diagramas de clases. También se define un método miembro de la clase TinyCPPParser que sirve para recuperar el objeto Builder. il o El resto de las secciones del archivo de especificación gramatical se apega al ejemplo mostrado en:[ el capítulo anterior en la Figura 3.10. Contiene la especificación de tod& las producciones gramaticales que permiten realizar la ingeniería inversa, de acuerdo al esquema de traducción conceptual mostrado en la Tabla 3.2. Por ejemploJla regla 11.2 se implementa así: idhiocualificado I ); : id : ID builder->setCurrentNombre(id->getTextO.c-strO); En donde, idNoCtialificudo es el símbolo no terminal a la derecha de la producción; id es una &ueia específica de ANTLR, que hace las veces de variable temporal para contener el texto de la muestra; ID es el token en que deriva el símbolo terminal a la $emha y cuyo lexemu se almacena en la etiqueta anterior; encerrada entre llaves está la acción semántica implementada por el .método setCurreniNombre, propio del objeto builder agregado previamente en la clase TinyCPPParser en la sección de código; setCurrentNombre se parametriza con el ‘t lexema de ID. 89 CAPiTULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA 4.3.3 I m p l e m e n t a c i ó n del analizador semántico 1 L a irnplementación del analizador semántico se basas en las acciones sernánticas descritas 1 de manera abstracta en l a Tabla 3.2 del capítulo 3. El objeto builder agregado en el objeto analizador sintáctico TinyCPPParser es el encargado de concretar dichas acciones semánticas. L a Figura 4.8 expone los métodos y atributos del objeto builder al que corresponden las acciones semánticas para recuperar diagramas de clases UML. ClnverSoodaDiagramaBuilder - mPrototipoClase : CClase' - mCurrrentAcceso : CString - mCurrrentTipo : CString - mCurrrentNombre : CString - mCurrentValor : CString - rnCurrentParam : CString - mCurrentNumAtributos : int - mAtribAcceso : CStringArray - mAtribTipo : CStringArray - mAtribNombre : CStringArray - mAtribValor : CStringArray - mCyrrentNumMetodos : int - mMetodAcceso : CStringArray - mMetodTipo : CStringArray - mMetodNombre : CStringArray - mMetodParam : CStringArray - mMetodValor : CStringArray - mAgregaciones : CStringArray - mHerencias : CStringArray + getDiagrama ( ) : CGrafico' + crearLinea ( ) : CGrafico' + crearRectangulo ( ) : CGrafico' + setHerencias ( ) : void + checkHerencia ( ) : void + setAgregaciones ( ) : void + checkAgregacion ( ) :void + getClase ( ) : CClase' + crearclase ( ) : CClase* + setMetodosClase ( ) : void + SetAtributosClase ( ) : void + resetMiembrosClase ( ) : void + setCurrentTipo ( ) : void + setCurrentAcceso ( ) : void + cetCurrentNombre ( ) : void + setcurrentvalor ( ) : void + setcurrentparam ( ) : void - ,resetMetodosClase ( ) : void - resetAtributosClase ( ) : void I1 1 I1 I i! I Figura 4.8 Métodos y atributos de la clase InverSoodaDiagramaBuilder usados en los mecanismos de ingeniería inversa. 90 ... <T ':'. ?'R. . CAPiTULO 4:DESARROLLO Y PRUEBAS DE L A HERRAMIENTA ,, ., , ,*r- IMPLEMENTACIÓN DE ANALIZADORES Papel de atributos y métodos en el análisis semántico IJi Atributo Papel en e/ análisis semántico mPrototipoClase mCurrrentAcceso mCurrrentT/po Es un objeto dentro del cual se almacenan t&nporalmente los valores resultantes del análisis. Cuando se concreta la identificación de una entidad grafica clase entonces se toman 10svalores almacenados en este objeto para guardarlos en vectores de objetos CString. Almacenamiento temporal para tipos de acceso,, por d:efecto private. Cuando se concreta la identificación de una clase se almacena en mAtribAcceso o en mMetodAcceso. 4lmacenarniento temporal para tipos de variables, ~. I1 métodos u objetos. Cuando se concreta la identificación de una clase se almacena en mAtribTipo o mMetodTipo. También es usado para ! ibentificar ,, . relaciones . . . . de . . . agregación . . . . . . . . . . . .y. .herencia. . . I Almacenamiento temporal para nombre de varia-bies, ~ - ; objetos o métodos. Cuando se concreta la ilentificación de una clase se almacena en mAtribNombre o mMetodNombre. .... ....... I)lmacenamiento temporal para e¡ 'valor de variables u objetos. Cuando se concreta la identificación de una i dase se almacena en mAtribValor o mMetodValor. ! Para métodos aplica como el especificador virtual huro. ............. Almacenamiento temporal para 10spaiámetrosde métodos. Cuando se concreta la identificación de una -. clase se almacena en mMetodParam. il . . . ... -.. . Almacenamiento temporal que lleva cuenta del número de atributos que se han identificado para una entidad clase. l. ............... ....... . . . . . . Almacenamiento temporal en forma de vector que almacena objetos tipo CString. Contiene la totalidad de los accesos que califican a los atributos kecuperados para una entidad clase. Almacenamiento temporal en forma de vector que almacena objetos tipo CString. Contiene la totalidad de los tipos de los atributos recuperados para una entidad clase. ' ~ i ~ mCurrrentNo'mbre I . . _ .- mcurrentvaior mcurrentParam mCurrentNumAtributos mAtribAcceso ~ I ~i , 1 rnAtribTipo Tabla 4.1 Papel de los atributos y métodos del objeto builder en el análisis semántico. CAPiTULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA -- I1 1 . Papel de atributos y métodos en el análisis'semántico--(continuación...) I i 1A tributo ..- ......... - - - ~ -! j Papel en el análisis semántico mAtribNombre Almacenamiento temporal en forma de vector que almacena objetos tipo CString. Contiene la totalidad de los nombres de los atributos recuberados para una entidad clase. .. .......... . mAtribValor Almacenamiento temporal en forma de vector que almacena objetos tipo CString. Contiene la totalidad de los valores de los atributos recuperados para una entidad clase. .... ........................................................................ ........... mCurrentNumMetodos Almacenamiento temporal que lleva cuenta del número de métodos que se han identificado para una entidad clase. mMetodAcceso Almacenamiento temporal en forma de vector que almacena objetos tipo CString. Contiene la totalidad de los accesos que califican a los métodos ! recuoerados oara una ,~ ............ entidad clase. -- 1 ,.I .................... .. ... ___ ... mMetodTipo iAiimacenamiento temporal en forma de vector que almacena objetos tipo CString. Contiene la totalidad de los tipos de los métodos recuperados para una t . entidad clase. . . . . . . . . . . de los nombres de los métodos recuderados para una entidad clase. Almacenamiento temporal en forma de vector que mMetodParam mAgregaciones j Almacenamiento temporal en forma de vector que almacena objetos tipo CString. Contiene la totalidad de las agregaciones encontradas durante el análisis I) semántico. ~ ~ ... ......................................................... ~ -. . ............................................. Tabla 4.1 Papel de los atributos y métodos del objeto builder en el análisis semántico. (continuación ...) /I 92 v"*r)+-.*." 'si.cl 11: CAPiTULO 4: DESARROLLO Y PRUEBAS DE L A HERRAMIENTA IMPLEMENTACldN DE ANALIZAOORES 4 Papel de atributosiiy métodos en el análisis sernántico (contin uació n.. .) Atributo Papel en el análisis sernántico mHerencias Almacenamiento temporal en forma de vector que almacena objetos tipo CString. Contiene la totalidad de las herencias encontradas durante el análisis smántico. Método Papel en el análisis sernántico r getDiagrama ( ) crearLinea ( ) -. . ___ crearRectangulo ( ) - . ... .. ..- .. .- setHerencias ( ) checkHeren2a ( ) seagregaciones ( ) checkAgregacion ( ) Retorna el objeto diagrama que se construye j r e a una figura del tipo Ciinea. Usado en la creación de entidades gráficas del tipo agregación o herencia. Resuelve las restricciones de despliegue de la figura dreada respecto a las clases que asocia y la agrega en el objeto diagrama . . _. Crea una figura del tipo CRectangulo. Este método se y tasa en los valores del objeto temporal clase para la creación de la figura rectangular. Resuelve las pstricciones de despliegue de la figura creada y la agrega en el objeto diagrama. .~ ~.~~. .~ . .. ... . Se encarga de asociar las herencias encontradas Clurante el análisis semántico con las respectivas clases. Recorre el atributo mHerencias para tal efecto. r - ~ .. ~ ~ .. . Ratifica en determinado momento del análisis semántico si el tipo y nombre temporales generará una asociación del tipo herencia. Si esto es afirmativo, I1 agrega una agregación a manera de objeto Cstring dentro del vector mHerencias. - .~ . . .. Se encarga de asociar las agregaciones encontradas i'lburante el análisis semántico con las respectivas I' clases. Recorre el atributo mAgregaciones para tal !efecto. Ratifjca'en determinado momento del análisis semántica si el tipo y nombre temporales generará una asociación del tipo agregación. Si esto es 1,afirmativo.agrega una agregación a manera de obieto I' [Cstrin !. dentro del vector-migregaciones. ~ . .. ~ ~ ~ ~ ~ ~~~ ~ 1 ~ ~ ~~ ~ ~~ ~ ~ Tabla 4.1 Papel de los atributos y métodos del objeto builder en el análisis semántico .(continuación ...) CAF'hlJLO 4: DESARROLLO Y PRUEBAS DE LA HERRAMENTA getClase ( ) crearclase ( ) Retorna el objeto temporal de tipo CClase Instancia el objeto temporal de tipo CClase con estado inicial vacío. I/ resetMiembrosClase ( ) setCurrentTipo ( ) setCurrentAcceso ( ) __ setCurrentNombre ( ) . _ . . _ I . setcurrentvalor ( ) setcurrentparam í resetMetodosClase ( ) __ recetAtributocClace ( ) -.___-___ ~~ I! ....... 1 Llama a resetMetodosClase y a resehtributosClase. .IAsigna un nuevo valor a la variable mCurrentTipo. Asigna un nuevo valor a la variable mCurrentAcceso. -/Asigna un nuevo valor a la variable-mCurrentNombre. 'risigna un nuevo valor a la variable m,CurrentValor. . __I_.~._I.__ siana un nuevo valor a la variable mCurrentParam. Limpia los valores temporales de los vectores que guardan información de los métodos de entidades clase. Limpia los valores temporales de los vectores que guardan información de los métodos de entidades :.I..clase. . . . . . . . . . . . . . . . . . . . ..~. il ' _ _ _ _ _ _ I - . . . 1 1 ¡I Tabla 4.1 Papel de los atributos y métodos del objeto builder en el análisis semántico. (continuación...) !t La tabla anterior corresponde a la descripción funcional de cada uno de los atributos y métodos mostrados previamente en la Figura 4.8, es decir, muestrailel papel de estas entidades en la irnplementación de los mecanismos de ingeniería inversa del objeto builder denominado InverSoodaDiagramaBuilder. ,I 94 ??,‘rutt”.‘* ,~ CAPÍTULO 4: DESARROLLO Y PRUEBAS DE LA g . >*. HERRAMIENTA PRUEBAS 4.4 Pruebas En esta sección se presentan dos casos de estudio a manera de pruebas. La intención primordial de estos casos de es&dio es constatar la validez de la hipótesis enunciada en el primer capítulo de este documento la cual sustenta que: ‘‘...esposible generar el diagrama de clases basado en el estándhr UML y los diagramas de Warnier para representar el diseño detallado de métodos de I)clases, apariir de código fuente existente en C++. ”. Es esencial mencionar que las pruebas realizadas son limitadas en ciertos aspectos puesto que no se realizaron bajo una evaluación exhaustiva ni bajo un estándar de pruebas de software. Por ejemplo, no se realiza un estudio de precondiciones ni poscondiciones que permitan validar la totalidad ?e los valores iniciales del código sujeto a prueba ni los valores de salida esperados. No obstante, los valores objetivos que se manejan en estos casos de.estudio son la correspondencia directa de las clases en el código fuente con las figuras tipo clase obtenidas en el diagrama de Clases; la validez en la cardinalidad de relaciones de tipo agregación y herencia; y, la validez en la cardinalidad, tipo, ámbito y nombre de los atributos y métodos de cada clase recuperada. Con las observaciones antes mencionadas se. presenta en las siguientes secciones los dos casos de estudio. 11’ 4.4.1 , Caso de estudio 1 El primer caso de estudio consiste en aplicar la ingeniería directa para modelar un conjunto de cinco clases, generar su iódigo y posteriormente obtener con ingeniería inversa el modelo correspondiente a partir del código generado. El conjunto de clases modelado corresponde a una porción de un prototipo de un framework estadístico, que fue desarrollado a manera de proyecto final para la materia de Ingeniería de Software Orientada a Objetos en el CENIDET’. El propósito general del framework es realizar cálculos de medidas de tendencia central, medidas de dispersión, ajuste de curvas, cálculo de distribuciones y ordenación de listas doblemente ligadas. Especídamente, la intención del conjunto de cinco clases elegidas para este caso de estudio es calcular la media aritmética, que es una medida de tendencia central; y la desviación estándar, que es una medida de dispersión. Enseguida se presenta la descripción de las cinco clases modeladas en cuanto a atributos y métodos: Clase Strategy . Atributos: Ninguno 11 ’ Esta prueba se realizó en colaborkión con el 1.S.C Manuel Alejandro Valdés Marrero, a quien quiero expresar un sincero agradecimiento por su ayuda en este caso de estudio. CAPfTULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA Métodos: public: void Calcula (Contexto *ctW ) = O public: double GetResult ( ) = O Clase Contexto I . I1 . .I I 1 - Atributos: private: double valor public: double Arreglo [ 10 ] public: Strategy str Métodos: public: void lnteractua ( ) public: void SetValor ( double dato ) public: double GetValor ( ) /I li Clases Suma, Media y Desviación ( heredan de Strategy ) . Atributos: private: double Resultado Métodos: public: void Calcula ( Contexto 'ctx ) public: double GetResult ( ) 11 La Figura 4.9 muestra el diagrama de clases producto de lalingeniería directa utilizandoÍnverSOODA: J r- ----- mi* I1 Figura 4.9 Diagrama de clases generado de manera asincrona por medio de la barra de modelado de InverSOODA. 1 96 PRUEBAS CAPITULO 4: DESARROLLO Y PRUE6AS DE LA HERRAMIENTA 11 A su vez, el diseño detallado de cada uno de los métodos de las clases de la figura anterior se creó con InverDDVi. Las siguientes figuras Y.. oárrafos describen más a detalle el diseño e intención de los métodos de cada clase. La Figura 4.10 de la presente página muestra en específico el diseño detallado del método Interactua de la clase Contexto. int ¡=O; i<l O; i++ { --- 1 El propósito de este método es utilizar en primera instancia, un ciclo para tomar valores desde la entrada estándar y almacenarlos en un arreglo. A partir de estos valores almacenados se calculan secuencialmente las siguientes medidas: b PSC PSC str=new Suman II str->Calcula[this] 1) Sumatona 2) Media aritmética 3) Desviación estándar SetValor[str->GetResultOJ I1 .' py."La -.. PSC PSC Sumatoria es: "<<GetValor0 I El proceso de cálculo para cada una de estas medidas estadísticas implica hacer la llamada a los métodos de un objeto Strategv en el siguiente orden: str=new Median str->Calcula[this] 1) Calcula i 2 ) GetResult SetValor[ctr->GetResult~] Pfl"La Media Aritmética e!: "<<GetValorO \' , PSC )I PSC PSC str-new Desviaciono Jj str->Calcula[this] SetValor[str->GetResupO) Desviación Estándar es: "<<GetValor[ .'.la . 41 Figura 4.10 Diagrama generado para la función Contexto :: Interachia 0. 11 1 97 El valor de regreso de la función GetResult se parametriza en la función SetVaior del objeto Cuntextu. Finalmente, se llama al método GetValor del mismo objeto Contexto, para imprimir el resultado del cálculo en salida estándar. Aunque también se generó el diseño detallado de los métodos SetValor y GetValor de la clase Contexto no se muestran en alguna ilustración debido a la simpleza de los mismos: sólo ejecutan una instrucción. CAPiTULO 4: DESARROLLO Y PRUEBAS DE LA H ERRAMIENTA I1 La Figura 4.1 1 muestra el diseño detallado 1 . s v m creado para el método Calcula de la clase concreta Suma. El propósito de este método es 11 realizar la sumatoria de todos los elementos double Surnatoria-O almacenados en el arreglo del objeto Contexto. PSC El resultado se almacena en la variable 11 Resultado, que es un atributo de las clases tipo Strategy. Para los métodos GetResult de cada una de las clases concretas de tipo Strategy también se realizó el diseño detallado, pero debido a la simpleza del método (realiza sólo una operación que regresa el valor contenido en la variable Resultado) no se incluyen las figuras correspondientes. Surnatoria~=~->Arreglo[i] ResultadoSumatoria Figura 4.1 1 Diseño ,;detalladodel método Suma::Calcula. 1 PSC PSC PSC PSC int N=l O double Surnatoria, rnedia=O Surnatoria=cb->GetValor0 rnedia=Sumatoria/N Recultado=media En el caso de objetos tipo Media, el método Calcula tiene la intención de calcular la media aritmética de los datos almacenados en el arreglo del objeto Contexto, pero utilizando la sumatoria de dichos datos previamente calculada por un objeto tipo Suma (recordar las instrucciones del método Interactua de la Figura 4.10), r h l t a d o que a su vez se almacena en la variable Valor del objeto Contexto (ver Figura 4.12). I ' La media aritmética calculada se almacena en la variable Resultado, que es un atributo de las I clases tipo Strategy (hablando en términos solamente del método Media::CalculaO ). :I En la página siguiente, la Figura 4.13 muestra el diseño detallado del método Calcula de objetos tipo Desviación. El proceso de cálculo de la desviación estándar se apoya en los cálculos Figura 4.12 Diseño detallado del previos por objetos Media (recordar las método Media::Calcula. instrucciones del método Interacpa de la Figura 4.10). Se utiliza la media almacenada en el obieto Contexto para calcular la diferencia de cuadrados con respecto a cada uno .de los elementos del arreglo. PSC I/ De lo anterior, se calcula la sumatoria de las diferencias al cuadrado para dividirla entre el número de datos. Finalmente, se obtiene la desviación estándar calculando la raiz cuadrada de la operación anterior. I1 98 ,, !I ~ CAPfTULO 4: DESARROLLO Y PRUEBAS DE LA PSC PSI: PSC ,t " PRUEBAS H ERRAMIENTA medio=cb<->GelValorO PSC PSC ' double Sumaioria=O, desv. media, aux " PSC e,.* inl N=10 PSC PSC .- ".: aux=m->Arreglo[i] - media Sumatoria+=aux*aux dcsv=Sumaloria/[N-11 I/ desv=sqrl[decv] Resultado=desv !! Figura 4.13 Diseño detallado del método Desviacion::Calcula. El código generado por InverSOODA correspondiente al diagrama de clases diagramas de las Figuras 4.94 es el sipiede: /'-----..---------------------------------------------.-~----------------------------------caso1.h */ / * Declaración de la clase. Cbdigo generado por InverSOODA * / //#if idefined(Contexto~compilada1 //#define Contexto-Compilada /* Descripción */ : class strategy; class Contexto ( / / Atributos public: double ~rregioiioli strategy *st=; private: double Valor; protected: CAF'hLO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA I / / Métodos public: Contexto0 ; -Contexto ( 1 ; void InteractuaO ; void CetValor(doub1e dato); double GetvalorO; private : protected: 1; //#endif / * Declaración de la clase. Código generado por InverSOODA * / //#if idefined(Strategy_Compilada) //#define Strategy-Compilada /* Descripción */ 1 : class strategy ( I/ / / Atributos public: private: protected: / / Métodos public: strategy ( ) ; -Strategy( ) ; virtual void Calcula(Contexto* ctX)=O; virtual double GetRecultO=O; private : protected: 1; //#endif / * Declaración de la clase. Código generado por InverSOODA * / //#if idefined(SumaCompi1ada) //#define Suma-Compilada /* Descripción : */ class Suma : public Strategy ( / / Atributos public: private: double Resultado; protected: / / Métodos public : Suma I ) ; -suma 1) ; void Calcula(Contexto* ctx); double GetResultO ; private : protected: / * Declaración de la clase. C6digo generado por InverSOODA * / //#if Idefíned(Media-Compilada) //#define Media-Compilada /* Descripción */ : 100 I/ '! CAPiTULO 4: DESARROLLO Y PRUEBAS b E L A HERRAMIENTA class Media : P RUEBAS public Strategy ( / / Atributos public: private: double Resultado; protected: / / Métodos public: Media I ) ; -Media ( ) ; void CalculaIContexto' double GetReSult O i private : protected: ctx); 1. Declaración de l a clase. Código generado por InverSoODA * / //#if Idefined(Desviacion-Compilada) //#define Desviacion-Compilada /* Descripción : */ class Decviacion : public Strategy ( / / Atributos public: private : double Resultado; ptotected: / / Métodos public : DesviacionO ; -üesviacionO ; void CalculalContexto+ ctx); double GetReaultO ; ; private: protected: 1; //#endif A su vez el código generado por InverDDVi correspondiente a los diagramas de la Figura 4.1O a la Figura 4.135 ed el siguiente: /*-----------------------------------.--~-..------------------.---.----.-------.~----~------. f */ caeo1.cpp #include "caso1.h" #include "math.h* #include "ioetream.h" / * Métodos de la clase. Código generada por InversOODA * / //#include I'S trategy.h" \ I Metodos de la clase Strategy Strategy::StrategyO I //Código I ' El c6digo fucnic en negritas fue sgrcgado o dercameniado de manera manual para qnc &te pudiera cornpilame y cjecularse. Posteriomcnic, las implementaciones .fueron 'agrupadas cn un solo archivo ( caso1 s p p )julo con CI código clienlc para quc pudiera realizarse la ingcnicna iwcma. CAP¡TULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA 11 Strategy: :-Strategy0 ( //C6digo /I 1 / * Métodos de la clase. Código generado por InverSOODA * / / / #include "Contexto.h'' / / Metodos de la clase Contexto Contexto::ContextoO { ValorFO ; ArreglollOl =ArregloliOI //Código h ; ) I/ Contexto::-Contexto0 í //Código I 1 void Contexto::InteractuaO I / / Código for (int i=o; icio: i++) { cout c < ',Valor"cci<c": cin >> Arreglo[il ; 'I; 1 1 str=new S u m a O ; str->Calcula(this); SetValor(str-sGetRecult01; =out << "La Sumatoria es: "<<GetValorO; Str=new Media0 ; str->Calcula(this); setvalor(str-~GetResultO): =out < < "La Media Aritmética e s : 'ccGetValor0; str=new DeeviacionO; str->Calcula(this1; CetValor(str-)GetResultO); =out < < "La Desviación Estándar es: "CsGetValorO; void Contexto::SetValor(double dato) 1 //Cbdigo Valorxdato; double Contexto::GetValorO ( //Cbdigo return Valor: 1 / * Métodos de la clase. C6digo generado por InverSOODA * / / / #include -5uma.h" / / Metodos de la clase Suma Suma ; :Suma ( 1 { //Código ReCultado=O : 1 Suma : ! -Suma ( ) { //Código 1 void Suma::Calcula(Contexto* ctxl ( 102 I/ !! PRUEBAS CAPiTULO 4: DESARROLLO Y PRUEBAS DE L A HERRAMIENTA '11 //Código double Sumatoria=O; for (int i=ü; i<lo; it+) ( Sumatoriat-ctx->Arregloíil: 1 1 /I ReSultado=SUmatOria; double Suma::GetResultO ( //Código return Resultado; I / / Media.cpp / * Métodos de la clase. Código generado por InverSOODA * / / / #include "Media.h* I / Metodos de la clase Media Media: :Media0 { Resultado=O //Código ; I I Media::-Media0 l ;/Código I void Media::Calcula(Contexto* ctxl - I .IICódiaa . int N=10; double Sumatoria. media=O; Sumatoria=ctx->GetValorO; media=Sumatoria/N; Resultado=media; double Media::GetResultO ,( //Código return Resultado; ) / / Des"i*Eion.Cpp 11 8, I* Metodos de la clase. C6digo generado por / / #include 'desviacion.h" / I Metodoc de la clase Desviacitin Desviacion::OecviacionO ( Resultado=O : //CSdigo SOODA 1. I Desviacion::-Desviacion() ( //Cbdigo !I I void Desviacion::Calcula(Contexto* C t x ) ( //Cbdigo int N=iO; double Cumatoria=O. desv. media. aux; media=ctx-,GetValoT(I i for (int i.0; i<iü; i++) ( 103 *I I) CAPITULO 4: DESARROLLO Y PRUEBAS DE L A HERRAMIENTA aux-ctx->Arregioiil Sumatoria+=aux*aux; ) il I - media; 1 desv.suma toria/ (N-11 ; dew-sqrt idecvl ; Resultado-desv: contexto ctx; c t x . 1nteractuao ret"rn o; !! ; Una vez compilado el código mostrado con anterioridad se puede correr la imagen ejecutable creada. La Figura 4.14 muestra la pantalla de salida de dicha corrida con datos I1 arbitrarios. I/ Figura 4.14 Pantalla de salida en la ejecución del código generado con los mecanismos de I/I1 ingeniería directa de InverSOODA. El proceso de ingeniería inversa con InverSOODA e InverDDVi se aplicó sobre el código generado con el proceso de ingeniería directa aplicado previamente en este caso de estudio. El resultado de este proceso de ingenieria inversa fue satisfactorio en cuanto a recuperación de los diagramas de clases y el diseño detallado de los métodos de estas clases, bajo las restricciones siguientes: - 1 Se comentó el código que fue insertado manualmente'. Remitirse al código ejemplo mostrado con anterioridad. Éste tiene señalada cn negritas el código que se comentó para que funcionaran los mecanismos de ingenieria inversa. 104 CAPiTULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA !I. - - 4.4.2 PRUEBAS AI arreglo declarado en la clase Contexto también se le comentaron los corchetes para quedar como variable simple. Se creó un Ünico archivo en el que integró la totalidad del código disperso en a’kchivos individuales, esto es, para los archivos de cabecera con las definiciones de clases. Los diagramas recuperados concuerdan con los creados originalmente en la ingeniería directa, aunque se tuvieron que reacomodar espacialmente para una mejor visualización. Caso de estudio 2 En el segundo caso de estudio se aplicó ingeniería inversa a dos conjuntos diferentes de clases relacionadas. Los conjuntos se denominaron arbitrariamente BDSys y EDMenu. Los conjuntos constan es su totalidad de catorce clases. El código fuente legado en C++ que contiene las catorce clases, es el resultado de un proceso de reingeniería descrito en los trabajos Brevemente se citan enseguida algunas de las intenciones y características del código fuente tomado para este segundo caso de estudio, extraídas de panoil: BDSys: “BDSystem es un programa .;escritoen lenguaje ‘ C , hecho para el sistema de control de procesos distribuidos para los módulos del sistema SAC del departamento de instrumentación y control del Instituto de Investigaciones EIBctricas. La función del sistema es la de manejar dos tablas de datos, una d e las señales analógicas y la otra de señales digitales para un sistema de control de procesos distribuidos.” It BDMenu: “BDMenu es un programa escrito en lenguaje ‘C’ que funciona como cliente de las operaciones que realiza BDSystem. La función’[deeste sistema es proporcionar al usuario un menu de opciones para las operaciones que puede realizar el BDSystem” El lector notará que se habla del lenguaje ‘C’ en las descripciones anteriores; afortunadamente, el código fuente tomado para esta prueba no es precisamente el programa en lenguaje C, sino el código! fuente producto del proceso de reingeniería descrito por pnnozl; dicha reestructuración permitió contar con un conjunto de clases que tienen la misma funcionalidad que el código original en C. :I Enseguida, se lista el código utilizado en esta pmeba’, seguido de una figura que corresponde a su diseño recuperado: Código fuente’ de las definiciones de clases de BDSys y de BDMenu: :I ’Aparecen en negritas las porciones de código que se alteraron para poder aplicarles eficazmente la ingeniería inversa. Esto significa que algunas lineas están comentadas, o bien tiene partes modificadas, incluso el código mostrado adolece de algunas líneas de preprocesamiento originales y presenta nuevos comentarios. No es posible generar una imagen ejecutable a partir de este código fuente debido a todas las modificaciones anteriores 1 CAPiNLO 4: DESARROLLO Y PRUEBAS DE LA HERRAMI ENTA /. ll!. ............................................................................ using namespace BDMenu; * class aStratl .............................................................................. class aStratl '1 ( protected: unsigned VAR; unsigned VALOR; public: virtual void AlgOritmODeInterfazO = O ; /' ......................................... :I * using,name?pace BDMenu; class Contexl ........................................... f I/ unsigned int getnum0 int pidevar ( 1 int pideval O int pidegrupo 0 ); class Contexl ( private : astratl Strategy; / / *strategy; public: /* contexio { Strategy >;*/ 1; - */ .. I1 ................................... */ NULL; void SetTipoO;// char)> void InteractuaO; /........................................................................ 1- - - - - - - * using namespace BDMenu; class CStT11 ........................................................................ ., .....* / class CStrli: public astratl I public void AlgoritmoDeInterfaz(), ); /' ............................................................................. * Using namespace BDMenu; * class CStrlZ .............................................................................. class CStrlZ: public aStratl ( public: void AlgoritmoDeInterfazO; , 1; !I *I . /.............................................................................. * using namespace BDMenu; class cStr13 .............................................................................. f class cStrl3: public astratl ( public : void AlgoritmoDeInterfazO; ); */ 106 ........ - . CAPhWLO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA 107 PRUEBAS CAF'h'WLO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA /I ( orivate : protected: public: ned int CK; ,-BASE O ( I; CK P O; */ 11 .I 1; virtual virtual virtual virtual virtual virtual virtual void bdinicia0; int bdescb0; //unsigned int bdescbw0; //unsigned int bdesca0; //unsigned int bdleeb0; //unsigned int bdleebw0; //unsigned int bdleea0; //unsigned int, unsigned intl; int, unsigned int); int. unsigned int); int); inti; inti; /' ............................................................................. * using namespace B u s y ~ ; * class VA1 I public: */ It class VA1: public BASE ( private : unsigned int VA; / / [30001 ; protected: I/ /*VA10 or V A 1 0 (unsigned int v-VA130001) t I*/ ); I I VA130001 D v~VA[30001; void bdinicia0; int bdleea();//unsigned int VAR); int bdesca()://unsigned int VAR. unsigned int VALOR); private: unsigned int VE; / / 12001 ; protected: public: /*VE10 (1; VBlluneigned int v-VBi2001 I ( I VB[2001 E V~VE~ZOOI, "I void bdinicia0; int bdleebO;//unsigned i n t VAR); int bdleebwO;//unsigned int GRUPO); int bdescb(l;//unsigned int VAR. unsigned int valor); int bdescbw();/./unsigned int GRUPO, unsigned int VALOR); 1; II CAPiTULO4: DESARROLLO Y PRUEBAS D E L A , HERRAMIENTA P RUEBAS La Figura 4.1'5 es el diagrama de clases correspondiente al listado de código anterior, recuperado con InverSOODA: 11 I u Reviredl ~~~ ~. __. -- ~~~ ~ ~.~L . . L 1 I1 Figura 4.15 Diagrama de clases recuperado con InverSOODA: despliegue las clases de " BDSys y de BDMenu. La recuperación del diagrama de clases de BDSys y de BDMenu implicó realizar previamente los siguientes pasos: - I1 Unir en un solo archivo con extensión hpp la totalidad del código de los archivos de cabecera dispersos, es decir, todo archivo con solamente definiciones de clases. Comentar toda directiva de preprocesamiento. Reescribir toda línea de código que tuviera que ver con apuntadores, de manera 'i) que se prescindiera de éstos. Comentar toda implementación inline. Comentar todo constructor. Reescribir toda Cunción con parámetros, de manera que se tuviera una versión de la misma función sin parámetros. ' - - - Ii 109 CAP¡TULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA 81 De este párrafo en adelante, la exposición los resultados de la fbtención del diseño detallado de cada uno de los métodos de las clases de B D S p y BDMenu, es de la siguiente manera: la porción de código del método adyacente a la ilustración $desde la Figura 4.16 hasta la F i b r a 4.3 1) con el diieño detallado correspondiente. 'i /' ............................................................................. / / from aCtratl.hpp: ex inline function unsigned int astratl ( I i: getnumii char s [ S O I : gets is1 i return iatoi i s ) ) ;. */ I1 I1 .. I¡ I1 Figura 4.16 Diseño detallado recuperado del método aStratl :: getnum(). I1 / * ............................................................................. I / from aStratl.hpp: ex inline function t int aStratl i: pidevar */ il printf (Itdame el NUMERO de la variable VAR = getnum i l i : "i; / / added ) return 01 '11 Figura 4.17 Diseño detallado recuperado del método aStratl :: pidevar (). 1 IO CAPh'ULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA . PRUEBAS . / ^ ............................................................................. I / from aStratl.hpp: int astratl I ) i: ex pidevalo inline f u k t i o n printf("dame el VALOR VALOR = getnum O ; de'la variable / / added return O ; : *I ',I; '! .,I -1U-1 U*J k!rx 5 PSC "dame el VALOR de la variable VALOR= getnum : '' 0 4 Fi&ra 4.18 Diseño detallado recuperado del método aStratl :: pideval 0. /' ............................................................................. / { from aStratl.hpp: ex inline function int astratl I I i: pidegrupo0 printf ("dame el NUMERO del grupo VAR = getnum ii ; .. *I) *I ,. / / added return O; Figura 4.19 Diseño detallado recuperado del método aStratl :: pidegrupo 0. 111 ... 11 1 AlgoritmoDelnteríaz d a d ipide I/ Figura 4.20 Diseño detallado recuperado del método cStrl1 ::AlgoritmoDeInterfaz(). ;/ cstr12 .cpp void cStrl2 : : AlgoritmoDeInterfaz I 1 I 1 printf ('LEE ANALüGICO\ntO ; pidevar ( ) ; d a 2 A{ AlgoritmoDelnteríaz 2D a $/ <. , "LEE ANALOGiCO\n" 1 pidevar I! lb I I/ I1 Figura 4.2 1 Diseño detallado recuperado del método cStrl2::AlgoritmoDeInterfaz(). ,I 112 PRUEBAS CAP~TULO 4: DESARROLLO Y P RUEBAS DE L A HERRAMIENTA /' ............................................................................. / / cstr13.cpp */ void cStrl3 : : A l g O r i t m O D ~ I n t ~ ~ f ~ ~ O { printf ("LEE BINAR10 POR GRUPO\n"l ; pidegrupo 0 ; I 1 d a d AlgoritmoDelnterfaz d a d ,I .s &<*/ "LEE BINAR10 POR GRUPO\n" lPidegruP0 I) Figura 4.22 Diseño detallado recuperado del método cStr !3::AlgoritmoDeInterfaz(), Ji Figura 4.23 Diseño detallado recuperado del método cStr14::AlgoritmoDeInterfaz(). 113 CAPfTULO 4: DESARROLLO Y PRUEBAS DE LA HERRAMIENTA printf ("ECC ANALOGICO\n"I : pidevar 1) : pideval I); 1 -1D - 1 I Figura 4.24 Diseño detallado recuperado del método cStrl5::AlgoritmoDeInterfaz(). /* / I cStrl6.cpp void cStrl6 ( I :: *I AlgoritmoDeInterfazO printf ["ECC BINAR10 POR GRUPO\n") pidegrupo í ) ; pideval O i 1 i AlgoritmoDelnterfaz -In2 py-"ESC BINAR10 POR GRUPO\n" 4 .lpidegrup .lpideval Figura 4.25 Diseño detallado recuperado del método cStrl6::AlgoritmqDeInterfaz(). 114 PRUEBAS CAPITULO 4: DESARROLLO Y PRUEBAS DE L A HERRAMIENTA I, I1............................................ / * ................................. / / SC-BASE.Cpp BASE 'SC-BASE::ProduceO { t return C r e a O ; -Yrea 115 */ CAPITULO 4: DESARROLLO Y PRUEBAS DE L A HERRAMIENTA J. !I ............................................................................... : : bdescalunsigned int VAR. unsigned int VALOR) int VA1 1 if W A R I 1 else ( 5 / 3000) printfí" ERROR . . . EL NUMERO DE LA VARIABLE ES > QUE EL TOTAL\n"); printf 1'' DE VARIABLES DE LA BASE DE DATOS \n'O ; I, I * deshabilita interrupciones * / / * suma e l nuevo valor y resta el valor anterior*/ I CK += (VALOR - VA[VARII; VA [VARI= VALOR; / * habilita interrupciones * / t ) return (VALOR); 1 ., ' II 2 0 2 A( bdesca unsigned int VAR unsigned int VALOR o 2 0 2 ' VAR 30002 0 2 .4 -.. y/. <., Areturn "ERROR,.. EL NUMERO DE LAVARIABLE ES > QUE ELTOTAL\n" 81 DE VARIABLES DE LA BASE DE DATOS \no' I) VALOR Figura 4.3 1 Diseño detallado recuperado del método VA1::bdsca (unsigned int VAR). Respecto a la recuperación del diseño detallado sólo se encontraron los siguientes detalles: - Se necesitó guardar en un archivo aparte las definiciones de métodos inline, para poder realizar la recuperación de su diseño. 4.5 Referencias [San021 Santaolaya Salgado. Re"& Modelo de Represeniaci6n de Palrones de C6digo para la ConstniccMn de Componentes Reusables. (Tesis de Doctorado. Instituto Poltecnico Nacional. Centro de Investigación en wmputaci6n. Laboratorio de ingeniería de Conware. México D.F. Noviembre de 2002). Capítulo 5 “What else could I write?, I don’t have the right..:” K. Cobain 5.1 5.2 5.3 5.4 Análisis de los resultados obtenidos Conclusiones Trabajos Futuros Referencias ANALISIS DE LOS RESULTADOS OBTENIOOS CApiTuLo 5 : CONCLUSIONES En el presente capítulo se presenta en primera instancia un análisis de los resultados obtenidos en las pruebas descritas en el capítulo anterior. Así mismo, a partir de l a experiencia obtenida durante el desarrollo en general del proyecto y primordialmente del análisis de los resultados se enuncian las conclusiones a las que se llegaron. Además, en l a ' última sección se menciona una't serie de recomendaciones a manera de trabajos futuros. 1 5.1 Análisis de los resultados obtenidos I, Como se indicó en los casos de estudio del capítulo anterior, los resultados obtenidos respecto a l a eficacia de la herramienta para recuperar diseños son satisfactorios, k apegándose a las limitaciones y alcances mencionados en l a Sección 1.6 de este documento. U n a serie de deficiencias de InverSOODA e I n v e r D D V i no descritas con anterioridad fueron detectadas durante las phebas. Se resumen a continuación las más importantes: Deficiencias encontradas durante las pruebas I :1 Deficiencia A:.: ....... ........... L.1 I.:I:.:. -::1 ................ -.............. Motivo .. ................... ... 1 El área de aplicación no tiyne habilitado el . El control del área de desplazamiento o área crecimiento 'del área de visualización ;de scroll como mejor se le conoce, está controlada por las barras de dksplazamiento: supeditado a.la función SetScrollSizes propia j de los objetos tipo CView de la MFC. Se I necesita asignar un valor más ,grande al área de desplazamiento si ai comparar este último contra el valor del área de la ultima figura 11 clase recuperada es menor. --L . . _ . . . _ _ I ..... . ~ .............. ~ )I : ~ 1 ^ _ No se admiten parámetros en las funciones. ~. ! ~ . No puede recuperarse el sin un tipo de dato de . 11 ............ El analizador sintáctico no tiene definida una regla gramatical que los produzca .......... ....... i~ . El analizador sintáctico no las define, pero por i otro lado incluirlas puede producir una ambigüedad con los constructores. ~~ 121 ~~ CAPhULO 5 : CONCLUSIONES ............... . .. ..... ...... ..... . . . .... ... .... ,. . ..,.. .... . .. . herencia de manera bidireccional. . . .-......-. . . ... . . I/ .. . __ Se tuvo que deshabilitar una serie de reglas que evitaban recuperar diseños que tuvieran legitimamente una relacibn de herencia y otra de agregación a la vez, entre dos clases. ~ ~ ~~ ~ - I 11 Tabla 5.1 Deficiencias encontradas durante las pruebas a InverSOODA 5.2 Conclusiones I1 A pesar de la existencia de las limitaciones y alcances sugeridos en el primer capítulo y la detección los errores de ejecución o bugs introducidos durante las phebas, la hipótesis que sostiene la tesis de este trabajo está comprobada: fue posible recuperar los diagramas de clases UML y el diseño detallado de los métodos de clases en diagramas de Warnier. I1 Siempre será más fácil comprender el todo de un sistema de software a través de un diagrama que infiltrándose en las peculiaridades del código fuente. Particularmente para los sistemas escritos en C++, el diagrama de clases provee una vista estátiza del sistema en la que salta a las vista cuantas clases existen, cuantas herencias, agregaciones y demás relaciones existen. I. En un proceso de desarrollo de software más o menos ordenado el diagrama de clases puede comunicar eficazmente las ideas generales del diseñador hacia alblprogramador. Más aún, cuando ya existe el software,. las personas encargadas del mantenimiento del software verán con gratitud una herramienta que les permita desentrañar dicho código existente. Mejor aún, tanto en etapas de diseño como de mantenimiento de sistemas escritos en C++ la posibilidad de crear o recuperar diseños' detallados de métodos, permitirá que las personas involucradas en el desarrollo se comuniquen con un nivel de abstracción mayor I/ que el código fuente. Considerando las acotadas dimensiones del proyecto (InverSOODA es un módulo de un proyecto más grande y ambicioso) y que no se tiene precisamente un &~po de trabajo al estilo industrial, se tiene que el aporte de este proyecto es potencialmente útil para la comunidad nacional de investigación en el área de Ingeniería de Software La necesidad de contar con una herramienta que maneje ambos aspectos, el diseño estático de clases y el diseño detallado encuentra una solución con InverSOODA. Además, la reestructuración de la arquitectura original de SOODA con algunos patrones de diseñy, presupone una escalabilidad más fácil a posteriori de la herramienta. La herramienta plantea un esquema simple de recuperación de diseños en términos del archivo de especificación gramatical y de los objetos involucrados en el proceso.'El USO de un objeto constructor que obedece al patrón de diseño Builder permite encapsular todo el proceso de análisis semántico en un solo objeto, conservando las responsabilidades de los objetos lexer y parser generados con ANTLR de realizar el análisis lkxico y sintáctico respectiva y Únicamente. Esto significa que, a la postre, se puede intercambiar la funcionalidad del análisis semántico con otro parser más completo para analizar código 122 CAPfTLiLO 5 : CONCLUSIONES CONCLUSIONES ; fuente en C++' y por ende, reLonocer más construcciones gramaticales del lenguaje, sin alterar la recuperación o uso de información semántica ya implementada. InverSOODA puede ser empleada en ambientes académicos para promover la enseñanza de sistemas orientados a objetos aportando el aspecto de diseño orientado a objetos. En conjunto con los demás módulos descritos en la Sección 1. 5.3 Trabajos Futuros Los resultados obtenidos en este proyecto permiten pensar en una cantidad importante de mejoras al software para abrir más perspectivas de uso práctico. Enseguida se enlista a manera de trabajos futuros, alghnas de las mejoras, quizá las más evidentes: Q Quizá la deficiencia más importante de InverSOODA radica en su parser. El hecho de incluir un analizador sintáctico completo supone la apertura de un análisis semántico más concienzudo, que a la postre permita recuperar más entidades gráficas del diagrama de clases del UML. o Idear una estrategia para poder analizar código con directivas de preprocesamiento, excepciones, y namespbces; elementos que no necesariamente se usan en la teoría de la programación orientada a objetos y sin embargo promueven la construcción de software'robusto y porthble. o Atender las deficiencias que marca la tabla 5.1 de este capítulo para enmendarlas, o Integrar InverSOODAl e InverDDVi con las demás herramientas de la Suite CENIDET (ver la Seciión 2.1.2, del capítulo 2), para que pueda convivir con éstas en un Ambiente de Mokielado. o Integrar capacidad de zoornrning en los diagramas. o Proveer un vínculo con herramientas de reingeniería, como en para poder visualizar el diseño del código resultado de procesos de reingeniería. En otras palabras, permitir el uso de la funcionalidad de InverSOODA a manera deplug-in. [sanozl, o Aumentar la capacidad del software para realizar ingeniería round-trip para otros lenguajes de programación orientados a objetos. 5.4 Referencias [San021 Cantaolaya Salgado, Renb. Modelo de Represeniacidn de Paimnes de Cddigo pare la Consi~lccidnde Componentes Reusables. (Tesis de Doctorado, instituto Poitbcnico Nacimai. Centro de Invesügacibn en computación, Laboratorio de Ingenieria de Software. México D.F. Noviembre de 2002). De hecho, el 16 de febrero de 2003 apareció la versión graluita dc archivo de espccifieaci6n gramatical para nnaiiais léxico y sintaciico C++ para ANTLR. 1 123 Subconjunto de la Gramática de C t t utilizada en InverSOODA 81 El lector encontrará que existen reglas triviales en esta subgramatica. Por ejemplo, sean A,B,C E del conjunto de los simbolos no terminales de G . <A> ::= <B>; <B> ::= <C>, entonceskAz ::=<O y <A> ::= <B> es una produción trivial. La razón para incluir producciónes triviales se debe a que se deja abierta la posibilidad de expander más producciones alternas, que complementen la gramática sin perder el orden del estándar. Seccion I. Programa. I I/ 1.1 cUnidadTrad> : : = <dec'laracion> EOF E II Seccion 11. Expresiones. 11.1 cexprId> : : = cidNoCualificado> 11.2 cidiioCualificado> ::;= <id:ID> Seccion 111. Oraciones. 111.1 E 1 Seccion IV.Declaraciones. IV.l cdeclaracions : : = cdeclSirnple> i IV.2 cdeclsimples : : = csecDeclESp> clistaInicDecla> I1 clistaInicDecla>';' 1 csecDeclEsp> Il ' i ' I ; ' IV.3 csecDeclEsp> ::= cespecDecl> IV.4 cespecDecl> : : = cespecTipo> IV.5 cespecTipos I) ::= I I <especClase> cespecSlrnpleTipo> <esp&cElabTipo> IV.6 <especSimpleTipo> : : = cnombreTipo> 11 1 I I I <tipoflotante> ctipoEntero> 'bool' >;' A NEXO A ,I I/ IV.7 cespecElabTipo> : : = <claveclase> It IV.8 <nombreTipo> ::= 'identificador' IV.9 cespecFunc> : : = 'inline'['virtual' Ceccion V. Declaradores. 1) V.l <iistaInicDecla> : : = <listaInicDecla> ' , ' <declInic> i V.2 cdeclInic> : : = <declarador> I I v.3 I <declarador> ::= I cdeclInic> cexprIdz ' í ' exprrd ')' II /I V.4 cdefFunc> : : = E V.5 cdefFuncMiembro> : : = <metodovirtual> I V. 6 <metodosimple> <secDeclEspMetodoCirnple> <declarado:> : := V.7 <metodovirtual> I/ <metodoCimple> : := csecDeclEspMetodoVirtual> <declarador> <secDeclEspMetodoVirtual> <declarador> I = ' 1 'O' I/ v.8 <secDeciEspMetodoVirtual> : : = <especTipoRetFunc> 'virtual' 'inline' I I I I I 1 I I I 1 V.9 csecDeclEspMetodoCimple> <especTipoRetFunc> 'inline' 'virtual' 'inline' 'virtual' <ecpecTipoRetFunc> 'inline' cespecTipoRetFunc> 'virtual' 'virtual' <especTipoRetFunc: 'inline' 'virtual' 'inline' <especTipoRetFunc> cespecTipoRetFunc> 'virtual' 'inline' 'virtual' I/ 'virtual' <especTipoRetFunc> 'virtual' 'inline' I/ 'virtual' <especTipoRetFunc> 'inline: 'inline' <especTipoRetFunc> <especTipoRetFunc> 'inline' 11: ::= 1 I 1 V.10 <secDeclEcpFunc> : : = <ecpecTipoRetFunc> <especFunc> I 1 I <especFunc> <especTipoRetFunc> <especTipoRetFunc> <especFunc> V.11 <especTipoRetFunc> : : = <especSimpleTipo> I 'void' Sección V i a . Clases. VIa.1 <especClase> : : = <cabeceraclase> VIa.2 <cabeceraclase> ::= I { ' 1 I! <especMiembro> ' ) ' <claveclase> 'identificador' 126 t ".' f ANEXO A I '<claveclase> 'identificador' via.3 <claveclase> : : = 'class' I 'struct' I cclausulaBases 'union' VIa.4 cespecMiembro> : : = '<declaracionMiembro> I 1, I <declaracionMiembro> <especMiembro> cespecAcceso> % : ' cespecAcceso> <especMiembro> I : ' VIa.5 <declaracionMiembro> : : = <defFuncMiembro> ' ; ' 1 I I cdefFuncMiembro> <especSimpleTipo> <listaDeclMiembro> l;' S . ! VIa.6 clistaDeclMiembro>.i: : = <declaradorMiembro> I VIa. 7 <declaradorMiembro& clistaDeclMiembro> ' , ' cdeclaradorMiembro> <declarador> : := Sección VI(bis). Clases Derivadas. ' : ' cespecAcceso> <nombreTipo> V I b . 1 <clausulaBase> : : VIb.2 <especAcceso> 'private' ::= I 'protected'I 'public' Sección VII. Reglas de producción para tipos de datos. : :L 'float' I 'double' I 'long' 'double' VII.l <tipoFlotante> VII.2 ctipoEntero> ::= ¿tipoCaracter> I <tipoEnteroConSigno> I ctipoEnteroSinSigno> VII.3 ctipoEnteroConSigno> : : = 'signed' 'short' 'int' I I I I I I 1 I I I VII.4 <tipoEnteroSinSigno> VII.5 <tipoCaracter> ::= 1 I ::= I I I 1 1 'signed' 'long' 'int' 'signed' 'short' 'signed' 'long' 'signed' 'int' 'short' 'int' 'long' 'int' 'signed' 'short' 'long' 'int' 'unsigned' 'unsigned' 'unsigned' 'unsigned' 'unsigned' 'unsigned' 'unsigned' 'char' 'signed' 'char' 'char' 127 'short' 'int' 'long' 'int' 'short' 'long' 'int' 05-0336'