SElT SEP DGlT Centro Nacional de Investigación y Desarrollo Tecnológico cenidet Sistema para Identificación de Patrones de Diseño en Código C++ (IPADIC++) TESIS Que para obtener ei grado de Maestro en Ciencias en Ciencias Computacionales presenta Félix Agustín Castro Espinoza Directores de Tesis: M.C. René Santaolaya Salgado M.C. Olivia Graciela Fragoso Diaz Cuernavaca, Moreios Diciembre de 1999 Centro Nacional de Investigación y Desarrollo Tecnológico FORMA C3 REVISION DE TESIS Cuernavaca, Morelos a 06 de Diciembre de 1999 M.C. Máximo López Sánchez 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: Sistema para Identificación de Patrones de Diseño e n Código C t + (IPADIC t t 1, realizada por el C. Félix Agustín Castro Espinoza, y habiendo cumplido con todas las correcciones 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 La comisión de revisión de tesis do.& La;, L,,i,; G Dr. José Luis Liñan García U 1 Director de tesis1 AL,$-,. M.C. O h i a raciel raaoso - Diaz Director de tesis2 ' C.C.P. Dr. Javier Ortiz HernánddJefe del Departamento de Ciencias Computacionales INTERIOR INTERNADO PALMIRA s/N. CUERNAVACA. MOR. M E K O APARTADO msiM 5-164 CP 62050. CUERNAVACA. TELS.(73)12 2314.12 7613.18 7 7 4 1 , F A X ( 7 3 ) 1 2 2434 EMAIL [email protected] cenidet Centro Nacional de Investigación y Desarrollo Tecnológico FORMA C4 AUTORIZACION DE IMPRESI~NDE TESIS Cuernavaca, Morelos a 06 de Diciembre de 1999 C. Félix Agustín Castro Espinoza Candidato al grado de Maestro en Ciencias en Ciencias Cornputacionales 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: Sistema para me es grato comunicarle, que Identificaci6n de Patrones de Diseño en Código C + 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. +, INTEROR INTERNACO PALMlRA W. CUERNAVAM. MOR. MEXICO APARTADO POSTAL 5- 164 CP 62050. CUERNAVACA. TELS.[73)12 2314.12 7613.18 7 7 4 1 , F A X ( 7 3 ) 1 2 2434 EML [email protected] cenidet Dedico esta 'tesis a: Mis padres (Félix y María Elena), mis hermanos (Manuel, Blanca, Maribel, Luis Enrique, y Ma. del Rosario), y en general a toda mi familia y a todas aquellas personas que creyeron en mi, en especial a mi tia Llaya(Ma. del Rosario) y a mi abuela queta (Enriqueta). Gracias por el amor y cariño que siempre me han brindado. I Agradezco a: Antes que nada a dios por prestarme la vida y darme fuerza y valor para seguir adelante y lograr lo que me he propuesto. A mis asesores de tesis M.C. René Santaolaya Salgado y M.C. O h i a G. Fragoso D i u por darme mucho de su tiempo y compartir conmigo sus experiencias y conocimientos, ademis por ayudarme a salir adelante con este trabajo de tesis. Gracias por su sincera amistad. A mis revisores de tesis M.C. Humberto Hernández Garcia, Dr. Guillermo Rodriguez Ortiz y Dr. José Luis Liñan Garcia, por sus excelentes comentarios y sugerencias para mejorar este trabajo de tesis. A mis maestros y amigos M.C. Máximo López Sanchez, M.C. Hugo Estrada Esquivel, M.C. Margarita Martinez Leal, M.C. Juan Gabriel González Serna, M.C. Jose Luis Ramirez Alcantara, Dr. Rodolfo Pazos Rangel por compartir conmigo sus conocimientos y experiencias. A mis compañeros de generación Isaac, Faby, Sofia, Magda, Gloria, Jod, Santiago, Alfonso, Rogelio, Rocío, Alberto Mario, Edson, Nadira y Javier, por brindarme su amistad y apoyo, gracias. A mis amigos de Sonora Jesús, Mercedes, Leobardo, Javier Zatarain, Felizardo, Bog&, y en general a todas aquellas personas que siempre estuvieron conmigo en las buenas y en las malas, gracias por su amistad. A Javier Santaolaya del Centro de Cómputo, Doña Lupita y Mario de la biblioteca y a Lorena, gracias. Agradezco de una manera muy especial a Cecilia Mpez Romero por toda su ayuda, gracias. A la Secretaría de Educación Pública (SEP) por el apoyo económico que me brindó durante mi estancia en esta institución. Lista de Figuras . No de figura Descripción Página 1.1 Estnictura general de entradas y salidas de información del producto generado por este proyecto de tesis......................................................... 6 4.1 Resultado de aplicar el modelo a la estructura del patrón de diseño....... 27 4.2 Árbol de derivación del ejemplo ilustrado en la figura 4.1 ..................... 29 4.3 Estructura general de la herramienta....................................................... 30 4.4 Diagrama de clases en notación OMT de la herramienta ........................ 31 4.5 Entradas y salidas del módulo para transformar el código en C++ a su . . ........................................................................................ forma canonica 32 Ejemplo donde se visualizan entradas y salidas del módulo para transformación del código C++ a la forma canónica.............................. 34 Entradas y salidas del módulo para reconocimiento de patrones de diseño...................................................................................................... 35 Clases y relaciones que se deben ignorar al analizar un código fuente....................................................................................................... 36 4.9 Relaciones del cliente con clases abstractas y concretas......................... 36 4.10 a) Estructura mínima de clases del patrón Abstract Factory....................... 37 4.10 b) Estructura genérica de clases del patrón Abstract Factory...................... 37 4.11 Ejemplo donde se visualizan entradas y salidas del módulo para reconocimiento de patrones de diseilo.................................................... 41 4.12 Pantalla principal de la herramienta........................................................ 42 4.13 Opciones del menú Patrones de diseño................................................... 42 4.14 Opciones del menu Ayuda ...................................................................... 43 4.15 Ventana para seleccionar el archivo a analizar y buscar el patrón de diseño seleccionado................................................................................. 43 Resultado de seleccionar el botón examinar ........................................... 44 4.6 4.7 4.8 4.16 4.17 Resultado de seleccionar el botón código............................................... 45 4.18 Resultado de seleccionar la opción Pafrones del menú Ayuda .............. 45 4.19 Resultado de seleccionar la opción Acerca de... del menú Ayuda .......... 46 5.1 Dimensiones de un sistema de consulta .................................................. 50 5.2 pantalla principal de la herramienta ........................................................ 52 5.3 Pantalla después de la selección de un patrón ......................................... 53 5.4 Pantalla después de la selección del archivo a analizar.......................... 53 5.5 Resultado de buscar el patrón Abstract Factory ...................................... 54 5.6 Resultado de buscar el patrón Iterator ..................................................... 55 5.7 Resultado de buscar el patrón Composite............................................... 55 5.8 Resultado de buscar el patrón Abstract Factory en el código no constmido basándose en él ...................................................................... 56 Resultado de buscar el patrón Composite en el código no construido basándose en él........................................................................................ 57 Resultado de buscar el patrón Iterator en el código no construido basándose en él........................................................................................ 57 Resultado de buscar el patrón Abstract Factory en el código del patrón Composite.................................................................................... 58 Resultado de buscar el patrón Abstract Factory en el código del patrón Iterator .......................................................................................... 59 Resultado de buscar el'patrón Composite en el código del patrón Abstract Factory...................................................................................... 60 Resultado de buscar el patrón Composite en el código del patrón Iterator..................................................................................................... 61 Resultado de buscar el patrón Iterator en el código del patrón Abstract Factory..................................................................................................... 62 Resultado de buscar el patrón Iterator en el código del patrón Composite................................................................................................ 63 5.9 5.10 5.11 5.12 5.13 5.14 5.15 5.16 IV AI Representación gráfica de la relación de Herencia................................. 71 A2 Representación gráfica de la relación de Agregación............................. 71 A3 Representación gráfica de la relación de Asociación.............................. 72 A4 Representación gráfica de la relación de Instanciaci6n.......................... 72 B1 Estructura del patrón de diseño Abstract Factory................................... 74 B2 Estructura del patrón de diseño Composite ............................................. 75 B3 Estructura del patrón de diseño Iterator .................................................. 76 V TABLA DE CONTENIDO Dedicatoria......................................................................................................... . . Agradecimientos................................................................................................. Lista de Figuras................................................................................................... . Capítulo 1 INTRODUCCI~N ........................................................ i i1 i11 1 1 .1 Antecedentes .................................................................................................. ... 1.2 Descnpcion del problema .............................................................................. 1.3 Propuesta de solución.................................................................................... 1.4 Objetivos........................................................................................................ 1.5 Metodología................................................................................................... 1.6 Beneficios...................................................................................................... . . . 1.7 Alcance y Imitaciones ................................................................................... . . 1.8 Organización del documento......................................................................... . Capítulo 2 ESTADO DEL ARTE................................................. .. 2.1 introduccion ................................................................................................... 2.2 Trabajos relacionados .................................................................................... 2.2.1 Un método inductivo para descubrir patrones de diseño desde sistemas de software orientados a objetos................................................ 2.2.2 Identificación automática de patrones de diseño............................ 2.2.3 Recuperaci6n de diseño mediante búsqueda automática de patrones de diseño estructurales en software orientado a objetos............ 2.2.4 ingenieria inversa de diseño y detección automática de patrones de diseño en Smalltalk............................................................................. 2.2.5 Conclusiones................................................................................... . 8 9 10 10 11 11 12 12 Capítulo 3 MARCO T E ~ R I C O .................................................... 14 3.1 introducción.t................................................................................................. 3.2 Desarrollo de software basado en componentes (CBD)................................ 3.3 Modelo Orientado a Objetos .......................................................................... 3.4 Lenguajes de patrones..................................................................................... 3.4.1 Patrones de arquitectura.................................................................. 3.4.2 Patrones de diseño ........................................................................... 3.4.3 Idioms o patrones de código........................................................... 3.5 Gramáticas libres del contexto ....................................................................... 3.6 JavaCC........................................................................................................... 15 16 19 20 20 20 21 22 23 . Capítulo 4 MODELO CONCEPTUAL DEL SISTEMA.............................................. :...................................................... 24 4.1 Modelo canónico de representación de patrones de diseño ........................... 4.2 Arquitectura de IPADICtt ................................ :........................................... 4.2.1 Módulo para transformación del código C++ a la forma canónica 4.2.2 Módulo de reconocimiento de patrones de diseño .......................... 4.3 i n t e r f e al usuario.......................................................................................... 25 30 32 35 42 . Capítulo 5 EVALUACIÓN EXPERIMENTAL.................. . . . 5.1 Preguntas de investigacion ............................................................................. 5.2 Variables y términos de la investigación y sus definiciones......................... . . . 5.3 Hipótesis de investigacion............................................................................. 5.4 Definición de casos de estudio ....................................................................... 5.5 Instrumentos de medición aplicados .............................................................. 5.6 Resumen del procedimiento en el desarrollo del experimento...................... 5.7 Resultados de las pruebas ................... :.......................................................... 5.7.1 Caso de prueba 1............................................................................. 5.7.2 Caso de prueba 2............................................................................. 5.7.3 Caso de prueba 3 ............................................................................. 5.7.4 Caso de prueba 4 ............................................................................. 5.7.5 Caso de prueba 5 ............................................................................. 5.7.6 Caso de prueba 6............................................................................. 5.7.7 Caso de prueba 7............................................................................. 5.7.8 Caso de prueba 8 ............................................................................. 5.7.9 Caso de prueba 9............................................................................. 5.7.10 Caso de prueba IO ......................................................................... 5.7.1 1 Caso de prueba 11......................................................................... 5.7.12 Caso de prueba 12......................................................................... 5.8 Resumen de resultados ................................................................................... 47 48 48 50 51 51 51 52 52 54 55 56 56 57 58 59 60 61 62 63 63 Capítulo 6.CONCLUSIONES........................................................ 64 6.1 Conclusiones generales .................................................................................. 6.2 Trabajos futuros............................................................................................. 65 66 Bibliografía.......................................................................................................... 68 Apéndice A .Notación y definición de relaciones entre clases ............................ 70 Apéndice B. Patrones de diseño reconocidos en la tesis ..................................... 73 Apéndice C . Códigos obtenidos de Internet correspondientes a los patrones de 77 diseao.................... :.............................................................................................. Capítulo 1 INTRODUCCI~N Capítulo 1 En el presente capítulo se describen algunos puntos relevantes para entender la importancia de la tesis en el área de la Ingeniena de Software, de la misma manera se ubica al lector en el contexto en el cual se llevó a cabo la presente tesis. Ademb se describe el problema ai que se contribuye en su solución, los objetivos principales, la solución propuesta, la metodología seguida para resolver el problema, así como los beneficios y alcances de la misma. 1 Capitulo I INTRODUCCION 1.1 Antecedentes. Uno de los objetivos más importantes de la Ingeniería de Software es el diseño e instrumentación de métodos y tkcnicas que permitan producir software de calidad con un mínimo de tiempo de desarrollo. Uno de estos métodos es el desarrollo de software basado en componentes los cuales han sido previamente construidos y tienen probada su calidad. Entre los beneficios del desarrollo de software basado en componentes está su potencial para reducir costos, reducir tiempos de producción de software, y aumentar la confiabilidad, ya que los componentes de software deben ser verificados para prevenir errores en ellos; por lo tanto, facilitar el desarrollo de software basado en componentes sería de gran utilidad[NOV97]. Aunque el concepto de desarrollo de software basado en componentes comenzó recientemente a tener auge, no es nuevo, los primeros acercamientos a este enfoque lo aplicaron los desarrol!adores de software al hacer uso de las bibliotecas de programas que proporcionan 10slenguajes comerciales’. Con la aparición del modelo Orientado a Objetos se increment6 el apoyo para desarrollar software basándose en componentes, ya que el utilizar este enfoque a nivel de programación procedural, como es el caso del lenguaje ‘C’, es muy limitado, como ejemplos de tales limitaciones tenemos que los elementos de reuso son las funciones y/o procedimientos; con lo cual se tiene una gran cantidad de dependencias funcionales. El resultado de construir sistemas de software bajo el paradigma procedural son programas de una sola pieza, que por ser diseñados para resolver problemas específicos es muy dificil su empleo en la soluci6n de otros problemas aún del mismo dominio de aplicación. Además cualquier línea de código puede acceder a las estructuras de datos globales, lo que se ha venido reflejando, a través del tiempo, en los altos costos por el mantenimiento de este tipo de programas[SAN98]. Como se mencionó antenomente el concepto de desarrollar software utilizando componentes no es nuevo, sin embargo, hasta la actualidad no se ha logrado que la producción de software se haga bajo esta política, ya que esto implica: Una adecuada preparación de personal calificado para la construcción de software utilizando componentes en lugar de partir de la nada, también hace falta que la administración de las empresas productoras de software adopten una política de este tipo, así como que la propia organización sea adecuada para construir sistemas bajo este enfoque, además existe una gran demanda de herramientas de soporte, adecuadas y/o suficientes para aplicar este concepto en todo el ciclo de vida de desarrollo de software[ML95]. Algunas características que deben cumplir los componentes para que sean reusables son: que obedezcan a una arquitechira (diseño conceptual) bien diseñada, es decir, que tengan la forma de plantillas genéricas, en las que se vean disminuidos algunos problemas I Los lenguajes comerciales tales como C++, Java, etc.. normalmente cuentan con una biblioteca de programas que están listos para que el usuario los utilice, disminuyendo de esta forma el tiempo de desarrollo de los sistemas. 2 Capítulo 1 INTRODUCCI~N clases y objetos que son personalizados para rcsolver un problema de diseño general en un contexto particular". Un patr6n proporciona una descripción abstracta de un problema de diseño, así como de un arreglo general de elementos, c l a s s y objetos, que lo resuelven. En general un patrón tiene cuatro elementos esenciales: Un nombre, el problema. la solución y las consecuencias. El nombre representa una manija que :e puede utilizar para desctibir en una O dos 3 Capítulo 1 INTRODUCCI~N 1.2 Descripción del problema. El desarrollo de sohvare empleando componentes se propone como una forma de producción de software de calidad, Dado que utilizando estos componentes se pretende llevar a cabo de forma más eficiente el desarrollo de productos de software; se hace patente la necesidad de que dichos componentes estén debidamente probados para que puedan ser reusables. Sin embargo, un problema para los desarrolladores de aplicaciones de software es asegurarse que sus diseños cumplan con las características antes descritas para asegurar que sus propios desarrollos sean reusables y que en un momento dado puedan ser incorporados a una base de componentes. Una manera de hacerlo es verificando si el o los, componente(s) fueron diseñados tomando en cuenta un patrón de diseño, ya que si se cumple lo anterior se puede asegurar su calidad y también su reusabilidad. 1.3 Propuesta de solución. La meta principal de este trabajo es enfocarse a contribuir en la solución del problema mencionado anteriormente a través de lo siguiente: Se propone la formulación de un modelo canónico de representación de patrones de diseño, y la construcción de un sistema que utilice este modelo, para que a partir del análisis de la estructura de clases de un código escrito en lenguaje C++, realice un reconocimiento que permita verificar si dicho código fue diseñado tomando en consideración patrones de diseño, o si el código es parecido a patrón de diseño conocido. aim 1.4 Objetivos. 1. Construcción de un sistema que permita identificar en un código fuente escrito en C t e , algunos patrones de diseño. 2. Validar la hip6tesis: "Esposible la identijicación automática de patrones de diseño en código fuente, a través de la implemenfaciónde un modelo canónico de patrones de diseño ". 3. Formular un modelo canónico para la representación de patrones de diseño, 4. Reconocer al menos 3 patrones de diseño de los propuestos por Ench Gamma en su libro Design Pufterns[GAM95]. 4 Capitulo I INTKODUCCI~N 5 . Que esta tesis sea el punto de partida para investigaciones futuras en el área de patrones de diseño y reuso de software dentro del Grupo de Ingeniería de Software del cenideí. 1.5 Metodología La metodología adoptada para abordar el problema planteado, y además solucionar las deficiencias encontradas en las herramientas relacionadas con la propuesta en este trabajo (en el capítulo 2 se describen tales herramientas), es la siguiente: 1. Formulación del modelo canónico de representación de patrones de diseño. Para esto se hizo uso de la teoría de gramáticas libres del contexto, además de las caractensticas y funcionalidad de los patrones de diseño. 2. Definir la forma canónica de cada uno de los patrones de diseño que se tomarán en cuenta. Para esto se utiliza el modelo creado en el paso 1, así como la teoría de patrones de diseño. 3. Diseño e implementación de un sistema de transformación de código C++ a la forma canónica. En esta parte se utiliza el paradigma de programación orientada a objetos, relaciones entre clases, teoría de autómatas y compiladores, así como del lenguaje de programación Java y C++, además de las características y funeionalidad de los patrones de diseño que intervienen en la tesis. 4. Diseño e irnplementación de un módulo de reconocimiento para cada patrón de diseño. En este módulo se utiliza el paradigma de programación orientado a objetos, gramáticas libres del contexto, generador de analizadores sintáctieos (parsers) JavaCC (se da una descripción de esta herramienta en el capítulo 3), así como del lenguaje de programación Java, y las formas canónicas de los patrones de diseño involucrados en este proyecto de tesis. Se eligió para la codificación de la herramienta el lenguaje de programación Javs, ya que proporciona la ventaja de ser independiente de la plataforma de hardware y sistema operativo utilizado para ejecutar el sistema. La estructura general (información de entrada y salida) de este proyecto de tesis se muestra en la figura I . 1. 5 INTRODUCCI~N Capitulo 1 COdigo fuente I MMulode MMulo para tramfomacih dcl c6digo a la forma I AbswctF actory I 1 rCUHocimicn10 de parones dc Diseo Canhica Figura 1.I : Estructura general de entradas y salidas de información del producto generado por este proyecto de tesis. I 1.6 Beneficios. La terminación satisfactoria del proyecto de tesis proporcionó un gran avance ai conocimiento formal de los patrones de diseño y una gran contribución ai área de Ingeniería de Software, ya que se alcanzaron los siguientes beneficios: Se cuenta con un modelo para representación de patrones de diseño. Se permite identificar si un código de clases en colaboración puede ser reusable. Se cuenta con una herramienta que permita identificar si un código en C++ se construyó basiuidose en un patrón de diseño, lo cual representa un cierto grado de calidad en el mismo. Se cuenta con una herramienta para mejorar el proceso de entendimiento y mantenimiento de un programa [BRO--][KRA96]. 6 Capitulo 1 INTRODUCCION Se elimina el problema de compatibilidad entre plataformas de hardware y software, ya que la herramienta se desarrolló en lenguaje Java. La tesis representa el punto de partida para investigaciones futuras en el área de patrones de diseño y reuso de componentes de software. 1.7 Alcance y limitaciones, El proyecto de tesis abarca lo siguiente: Se formó la estructura canónica de los tres patrones de diseño que intervienen en la tesis (Abstract Factory, Composite, e Iterator). Se desarrolló e implementó el sistema para la transformación del código en lenguaje C++ a su forma canónica correspondiente. Se desarrolló e implementó el módulo de reconocimiento de los patrones de diseño involucrados. Se analizará únicamente código en lenguaje C++. En iPAD1Ci-t no se verifican errores en el código analizado, por lo tanto el mismo no debe tener errores de compilación, ni ejecución. Las clases pertenecientes al código analizado pueden estar en uno o en varios archivos, con la restricción de que en el mismo archivo deben estar tanto la declaración como la implementación de la clase. Para reconocer relaciones entre clases (Agregación y Asociación), deben esW declarados formalmente los objetos. 1.8 Organización del documento. En el capítulo 2 se describe el estado del arte en tomo ai trabajo de tesis, se mencionan y analizan los trabajos relacionados con la herramienta desarrollada en la tesis, además se hace una comparaci6n entre tales trabajos e IPADIC++ con la finalidad de observar ventajas y desventajas. En el capítulo 3 se describe el marco teórico, es decir, se mencionan y explican aquellos fundamentos teóricos que sustentan este trabajo de tesis. En el capitulo 4 se da una descripción del producto generado por esta tesis, mencionando cada uno de sus módulos y explicando su funcionamiento y características. En el capítulo 5 se da una descripción de la forma en la que se llevó a cabo la evaluación experimental de la herramienta. En el capítulo 6 se describen las conclusiones observadas al evaluar la herramienta, así como los trabajos que se le realizarán a futuro a la misma. Capítulo 2 ESTADO DEL ARTE ,.' . . Capítulo 2 ESTADO DEL ARTE En este capítulo se describe el estado de la práctica actual en tomo al tema de patrones de diseño, así como los trabajos relacionados con la herramienta generada en este proyecto de tesis, IPADICtt, analizando sus características, ventajas y desventajas. Además se menciona cual es la diferencia de esta tesis con tales trabajos haciendo énfasis en la aportación de nuestro trabajo. 8 Capítulo 2 2.1 Introducción. ESTADO DEL ARTE < . En los últinios aílos surgió el término patrones de diseño y desde entonces ha sido motivo de intensa investigación, y prueba de ello son los niúltiples artículos publicados en diferentes congresos internacionales relacionados con éste importante tema; entre los tópicos más importantes que han captado la atención de los investigadores están: Formular nuevos patrones de diseño para resolver los problemas de diseño más dificiles de solucionar y que se presentan con mayor frecuencia en la construcción de sistemas orientados a objetos. Utilizar los patrones de diseño ya existentes para solucionar nuevos problemas. Relación entre el modelo orientado a objetos y los patrones de diseño. Detectar patrones de diseño en código fuente a través de un análisis del mismo. El tópico que más nos interesa por su similitud con el presente trabajo es el Detectar patrones de diseño en código fuente, por esta razón nos enfocaremos en esa parte a analizar tales herramientas. En la actualidad ya existen en algunas partes del mundo (no así en México) métodos no automatizados, y prototipos de herramientas que reconocen patrones de diseño en código fuente. Aquí clasificamos los trabajos anteriores de la siguiente manera, posteriormente se da una descripción más amplia de cada uno de ellos: Métodos no automáticos. Dentro de estos se encuentra el método inductivo para descubrir patrones de diseño desde sistemas de sofrware orientados a objetos, el cual realiza la detección de patrones de diseño en forma totalmente manual. Herramientas automáticas. Para realizar la detección se basan en información de diseño (relaciones entre las clases y objetos del código analizado) recuperada del cúdigo. Entre las herramientas encontradas de este tipo están: Identificación automática de patrones de diseño, Recuperación de diseño mediante bUsqueda automática de patrones de diseño estructurales en soflare orientado a objetos, e Ingeniería inversa de diseño y detección automática de patrones de diseño en Smalltalk 9 ESTADO DEL ARTE capítulo 2 2.2 Trabajos relacionados. 2.2.1 Un método inductivo para descubrir patrones de discño desde sistemas de soihvarc orientados a objetoslSHU961. En este artículo se presenta un método inductivo’ (no automático) que ayuda a descubrir patrones de diseño en sistemas de software orientados a objetos. Proporciona un conjunto de procedimientos definidos rigurosamente para que puedan ser repetibles y utilizables por personas que no están familiarizadas con procesos de ingeniería inversa. El método propuesto aquí se denominó BACKDOOR (Backwards Architecture Concerned with Knowledge Discovery of O 0 Relationships). La principal salida del proceso al aplicar el método es una base de conocimientos que describe que patrones han sido usados a la fecha por una organización. Una vez que se han identificado los patrones potenciales, son revisados por los demolladores para ver si existe algún significado en el conjunto de clases identificadas. Este método consta de 6 pasos secuenciales e iterativos: I . Revisión de la documentación de la especificación del problema Y el diseño. Se estudia la especificación del problema para identificar restricciones y tópicos del problema, así como para obtener ideas de la funcionalidad proporcionada. 2. Desarrollo de un modelo ureliminar del sistema desde la declaración de clases. Aquí se descubre como interactúan las clases (se revisa la declaración de las mismas); se detectan relaciones como herencia, comunicación entre clases, etc. 3. Refinar la notación de objetos desde la imulementación de las clases. Se da una mirada detallada al código de implementación de las clases, es decir, se revisa minuciosamente la implementación de las clases para tratar de identificar relaciones entre las mismas. 4. Utilizando el modelo refinado de la arauitectura del sistema, identificar candidatos potenciales a uatrones basados en herencia Y ligas de comunicación entre clases. Este paso se enfoca a relaciones interesantes en las arquitecturas, buscando similaridades eshucturales recurrentes. Relaciones como: clases “mediador”, “interfaz a otras clases”, “herencia paraiela”, “liga entre dos subsistemas”. 5 . Analizar los candidatos a Datrones detectados en el uaso 4. Aquí se hace una comparación de los patrones potenciales identificados en el paso 4 contra los patrones del conjunto de referencia. El conjunto de referencia al principio está compuesto únicamente por los patrones de diseño descritos por Erich Gamma en su libro, pero si después se detectan patrones de diseño nuevos estos se agregan al conjunto de patrones de referencia. ’ Se le denomina inductivo ya que, primero localiza patrones de diseno potenciales, posteriormente realiza una comparaci6n de ellos con los patrones de diseno existentes con la finalidad de hacer una mejor detección, además si encuentra patrones nuevos, los anexa al conjunto de patrones de referencia. I 10 ..- . capítulo 2 ESTADO DEL ARTE 6. Iniervención de diseiiodores e inidetrienfadoreesnora aclarar nroblenias de diseño. En este paso se tienen entrevistas con ¡os diseñad'ores y codificadores responsables para un mejor entendiriiiento del sistema. La información recabada en este paso se espera que sirva para retomar a los pasos 4 o 5 para una iteración más detallada. El método utilizado en el artículo es manual, por lo tanto requiere de mucha intervención por parte del usuario, lo cual le ocasiona una seria desventaja con respecto al método propuesto en la tesis, el cual es automático, y requiere menor intervención del . usuario para detectar patrones de diseño. 2.2.2 Identificación automática de patrones de diseño(BAN98]. En este artículo se presenta una herramienta (LIP++) que automatiza la detección, identificación, y clasificación de patrones de diseño en programas C++. DP++ actualmente identifica algunos de los patrones estructurales, y algunos de los patrones de comportamiento (Behavioral) descritos en el libro de Ench Gamma[ll]. Esta herramienta se basa en las relaciones estructurales entre las clases y objetos para identificar usos de patrones de diseño en programas orientados a objetos; relaciones estructurales como: clases abstractas, clases base y subclases, plantillas de clases (template classes), relaciones de herencia, agregación por contención física de variables de instancia, y agregación por referencidapuntador a variables de instancia. Esta herramienta utiliza un algoritmo de reconocimiento para cada patrón de diseño reconocido en ella. Además despliega una ventana con el modelo de clases de la estructura del programa, y una ventana con una vista de árbol que despliega la jerarquía de clases del proyecto. La principal desventaja de esta herramienta con respecto a IPADIC++, es que no detecta patrones de diseño de creación (creational patterns). 2.2.3 Recuperación de diseño mediante búsqueda automática de patrones de diseño estructurales en software orientado a objetos (KRA96). En este artículo se muestra una herramienta denominada PAT, en esta se extrae información de diseño directamente de los archivos de cabecera de C++ y se almacenan en un repositorio. Los patrones son expresados como reglas Prolog y la información de diseño es también trasladada; una simple consulta de Prolog es usada para la búsqueda de todos los patrones. En esta herramienta únicamente se reconocen instancias de algunos patrones de diseño estructurales mencionados por Ench Gamma [GAM9S], los cuales son: Adapter, Bridge, Composite, Decorator, y Proxy. 99-0648 11 Capítulo 2 ESTADO DEL ARTE Los pasos que sigue PAT para la bÚsqueda.de patrones de diseño son: 1. Cada patrón es representado como un diagrania OMT estático, estos diagramas constituyen el repositorio P (de patrones). 2. Un programa es usado para convertir P en una regla de Prolog para cada patrón de diseño. 3. Se utiliza la herramienta ooCASE para realizar el mecanismo de análisis estructural, ooCASE extrae información de diseño de los archivos de cabecera de Ctt y la representa en el repositorio en la notación OMT. La parte resultante del repositorio es llamada D (de diseño). La información relevante que es extraída de los archivos de cabecera de C++ es: nombre de clases, nombre de atributos, nombre de métodos, relaciones de herencia, y relaciones de agregación y asociación. 4. Otro programa es usado para convertir D en la representación Prolog. 5 . Una consulta Q de Prolog detecta todas las instancias de patrones de diseño de P en el diseño D examinado. La desventaja de PAT es que detecta únicamente patrones de diseño estructurales, y no detecta de creación y de comportamiento. 2.2.4 Ingeniería inversa de diseño y detección automática de patrones de diseño en SmalltalkjBRO--1. En este artículo se muestra una herramienta (KT) la cual recupera información de diseño desde código Smallfalk, y la. usa para detectar algunos patrones de disefio como son: Composite, Decorator, y Template Method. Además muestra el diagrama de clases del código analizado, utilizando la herramienta CASE Rational ROSE, para hacer esto, toma la información de diseño recuperada del código, después genera un archivo en el mismo formato que los archivos de diseño generados por Rational ROSE. 2.2.5 Conclusiones. Una de las limitaciones importantes de las herramientas descritas es que reconoen únicamente instancias de patrones estructurales, y son dependientes de la plataforma de hardware y sistemas operativos, ya que no se desarrollaron en un lenguaje de programación independiente de la plataforma como Java. 12 Capítulo 2 ESTADO DEL ARTE IDAPIC++ se desarrolló en lenguaje Java lo cual le proporciona una ventaja sobre las herramientas mencionadas anteriormente, al permitir poder ejecutarse en prácticamente cualquier plataforma y sistema operativo que soporte Java. IPADIC++ puede detectar un patrón de diseito de cada una de la clasificación propuesta por Erich Gamma, descritas en la referencia [GAM95]. Otra ventaja que posee IPADIC++ es que utiliza un Modelo Canónico para la Representación de Patrones de Diseño, lo cual le da formalidad a la solución utilizada para identificar patrones de diseño desde código fuente. 13 Capitulo 3 h4ARCO TEÓRICO Capítulo 3 MARCO TEÓRICO En este capítulo se describen los fundamentos teóricos más importantes que dan sustento a la investigación realizada en la tesis, aspectos como: desarrollo de software basado en componentes, lenguajes de patrones, gramaticas libres del contexto, modelo Orientado a Objetos, y la herramienta para generacion de analizadores léxicos y sintácticos (parsers) JavaCC. 14 Capítulo 3 MARCO TEÓRICO 3.1 Introducción. Es indispensable describir algunos de los fiindanientos teóricos utilizados en la realización de esta tesis, así como también la relación de los mismos con este proyecto. A continuación se describirá el contexto en el cual se relacionan tales conceptos con este trabajo. Con respecto al desarrollo de sofhvare basado en componentes, el contexto de relación es que este proyecto de tesis ayuda de cierta forma' a determinar si un software cumple con algunas caracteristicas para ser reusable, y ser incorporado a una base de componentes. El contexto de relación del modelo Orientado a Objetos con esta tesis es que los patrones de diseño emergen del modelo Orientado a Objetos, por lo tanto es necesario dar una descripción de este modelo. Además que IPADIC++ analiza código escrito en lenguaje C t t , el cual obedece al paradigma Orientado a Objetos. También el lenguaje Java utilizado para la codificación de la herramienta, es Orientado a Objetos. Debido a que PADICtl- detecta patrones de diseño a partir del análisis de código fuente, es necesario comprender y analizar este término, su relación con los demás tipos de patrones. La mejor manera de hacerlo es estudiando los lenguajes de patrones. La relación de las gramáticas libres del contexto con el tema de tesis se presenta porque, el modelo canónico de representación de patrones de diseño formulado en este proyecto consta de una gramática libre del contexto2, además que en el módulo de reconocimiento de patrones de diseño (ver capítulo 4) se utiliza una gramática del mismo tipo para generar el analizador (parser) que hará dicho reconocimiento. Aquí también se da una descripción del funcionamiento de la herramienta para generación de analizadores léxicos y sintácticos (parsers) JavaCC, ya que esta se utilizó para generar el analizador utilizado por el módulo para reconocimiento de patrones de diseño. A continuación se describen cada uno de los fundamentos mencionados anteriormente. I Se dice que de cierta forma, porque no analiza exhaustivamente el s o h a r e en cuanto a su calidad, sólo se miden algunos parhetros. que son los heredados de la utilización de a l g h patr6n de diseflo; con lo cual no se puede decir que el código analizado cumple con todas las caracteristicas de calidad necesarias para ser considerado como un componente. Decimos que consta de una gramática libre del contexto por el tipo de reglas de producción que posee. Capítulo 3 MARCO TEÓRICO 3.2 Desarrollo de software basado en componentes (CBD). Hace treinta años que empezamos a oír acerca de la crisis del software, la cual se ha traducido en la insatisfacción a la demanda de aplicaciones informáticas. Si bien es cierto que la capacidad computacional tanto en hardware como en software ha tenido un fuerte desarrollo en los últimos años, no se puede negar que también la demanda de sistemas de información se caracteriza por sistemas cada vez mas intolerantes a fallas y de mayor complejidad. Para agregar madurez al proceso[AHR95] de desarrollo de sistemas, una meta actual de investigación en ingeniería de software es la de otorgar facilidades en los procesos por medio de la adopción de herramientas automatizadas para construir, entender, mantener y documentar el software, conduciendo a una mejor calidad y confiabilidad, así como una mayor satisfacción del cliente. El desarrollo de software se está moviendo rápidamente de una forma artesanal hacia el proceso de ingeniería y manufactura a gran escala. Un mcvimiento hacia componentes de software está siendo manejado por la urgente necesidad de contar con artefactos de software reutilizable que cuenten con una mejor calidad, y que puedan ser confgurados en diferentes aplicaciones, para satisfacer las necesidades de cambio con un mínimo de inversión en costo y esfuerzo[TH095]. Los primeros componentes fueron llamados circuitos integrados de software, los cuales aparecieron como paquetes sellados con un conjunto especifico de entradas y salidas, a estos componentes se les conoce como mensajes, interfaces de aplicaciones (Mi’s) y protocolos[TH095]. Durante muchos años se ha visto al desarrollo de software basado en componentes como una de las técnicas más promisorias para enfrentar la crisis del software. Sin embargo, hasta hoy no se ha logrado establecer en su totalidad que la producción de sistemas se haga bajo una política de empleo de componentes, como un modelo de ingeniería. La comunidad científica de ingenieria de software ha propuesto varios paradigmas de programación para aliviar en parte este problema, con los cuales se gana un cierto nivel de reuso. Con el paradigma de programación procedural se permite a los programadores ejecutar segmentos de código, organizados en librerias de funciones, más de una vez, sin tener que duplicar el código en cada localidad física donde es necesario. También se pueden insertar subnitinas extraídas de otros programas desarrollados previamente. El paradigma de programación modular habilita el desarrollo de programas por piezas de código independientes. Los elementos de reuso ahora son los módulos ylo módulos compuestos que logran una mayor funcionalidad, para dar satisfacción a los requerimientos de nuevas aplicaciones. Para alcanzar un mayor grado de reutilización de código, el paradigma de programación orientada a objetos permite, además, adaptar un componente a nuevos usos o í6 Capitulo 3 h4ARCO TEÓRICO aplicaciones sin tener que modificar su definición actual. Los artecactos de reuso de este paradigma lo representan las diferentes configuraciones o comunidades de clases interactuando y organizadas en jerarquías de herencia denominados frameworks. En la actualidad, el desarrollo de sistemas basado en Componentes (CBD), representa el paradigma de construcción de software mas ampliamente aceptado y el de mas duración que sus predecesores. Este paradigma, va a desplazar a los arquetipos anteriores de programación, ya que se considera el enfoque más prometedor para obtener beneficios significativos en lo que se refiere a productividad y reusabilidad. CBD ofrece una oportunidad para construir arquitecturas que perdurarán hasta el siguiente siglo y promete formas o maneras para evolucionar soluciones en la fase de cambios de requerimientos de aplicaciones[SPI97]. El estado del arte de CBD indica dos direcciones, una apunta hacia el desarrollo y uso de frameworks los cuales definen a los objetos de reuso de dominios configurados mediante un modelo orientado 2 ubjetos, y la otra va hacia la definición de componentes de anaquel (COTS) que utilizan un modelo de infraestructura común. Los frameworks son colecciones de estados y comportamiento, modelados como una comunidad de clases interactuando y organizadas dentro de un número pequeño de jerarquías de herencias[TH095]. Los frameworks modelan dominios de aplicación particulares y requieren de un entendimiento profundo de programación y diseño orientado a objetos. Los arquitectos definen la esencia del framework usualmente en la forma de clases abstractas, y los diseñadores lo implementan proporcionando clases concretas que realizan el comportamiento. Un buen framework requiere de un gran conocimiento del dominio y experiencia en el desarrollo de frameworks. Las personas encargadas del mantenimiento (extendedores), mejoran un framework que está siendo utilizado por una familia específica de aplicaciones, lo cual permite especializarlo y extenderlo sin la tradicional re-programación asociada. Los frameworks pueden ser empacados como cajas blancas, grises o negras. Las cajas negras son completamente cerradas a las modificaciones y/o extensiones, mientras que las cajas blancas son totalmente vulnerables ya que permiten libre acceso a los detalles de implantación y a las estructuras. Las cajas grises son las más deseables porque ocultan los detalles de implantación y/o los aigoritmos propietarios y la estructura, que pudieran impactar la evolución del framework o su portabilidad. Por otro lado, trabajos recientes presentan a los patrones como un método promisono para describir a la estructura interna y el comportamiento de frameworks, desafortunadamente la mayoría de métodos de análisis y diseño orientados a objetos ignoran a los frameworks y asumen que todas las aplicaciones se construyen de manera rudimentaria. En esta dirección, la tendencia hacia el reuso de componentes de software se propone a través de arquitecturas basadas en patrones de diseño, librerías de clases y frameworks. Ai funiro se vislumbra que este enfcque influenciar&grandemente el desarrollo de software[WAT97]. Los componentes de tipo COTS son cajas negras, ensambladas y conectadas de acuerdo al principio de ocultación de datos. Por razones de mantenimiento y comerciales, estos componentes se empacan en formato de solo ejecución y, tal vez, con algo de código 17 Capitulo 3 MARCO TEÓRICO fiicnte como documentación[TH095]. Aunque muchos Componentes son implcmentados coi~ioobjetos, un componente no tiene que ser un objeto. Un componente solo necesita eiiipacar la funcionalidad de programas de tal forma que las capacidades del coiiiponente sea1 visibles por el contenedor durante el ensamble y en tiempo de ejecución. Por otro lado, está siendo muy común empacar aplicaciones legadas completas en arreglos de coriiponentes para ampliar el acceso a los datos que ellos manejan[SP197]. La producción de software basado en componentes, implica problemas que aún son temas de investigación[MIL95], tales como: la carencia de herramientas adecuadas y/o suficientes para apoyar todo el ciclo de vida del software, la carencia de personal calificado para desarrollar componentes, y la carencia de políticas en las organizaciones para construir aplicaciones bajo este enfoque. Por lo que, moverse desde la actual práctica de desarrollo de software dominada por grandes y complejas aplicaciones legadas, con un cúmulo de peticiones de desarrollo y mantenimiento por atender, hacia una generación de desarrollo de software basada en componentes y programación automática, ha probado mucha dificultad[AHR95]. Sin embargo, ya existen algunas tecnologías que pueden ayudar, !ales como: el Análisis e Ingeniería de Dominios, Herramientas CASE, Métodos de Análisis, Diseño y Programación Orientada a Objetos, Patrones de Diseño y Frameworks, nuevos Modelos de Arquitecturas, Ambientes de Administración de Componentes, etc. La evolución de los modelos del ciclo de vida del software ha sido constante, de los tradicionales modelos de cascada a los modelos más modernos como el de prototipos rápidos, implementados con interfaces interactivas que permiten producir so&are al nivel de prototipo de manera inmediata hasta lograr la satisfacción de los requerimientos del cliente o del usuario final. Una tendencia tecnológica actual es la definición de nuevos modelos del ciclo de vida del software, sobre los cuales se construyan ambientes de desarrollo que incluyan herramientas automáticas o semiautomáticas, visuales e interactivas, que cubran tanto el desarrollo de componentes como la constnicción de sistemas basándose en el uso de éstos. Margaret Burnett[BUR95] ha propuesto que los nuevos modelos de desarrollo de software contemplen al menos cuatro etapas: mecanismos para la clasificación y recuperación de componentes. mecanismos para el encapsulado de nuevos componentes, mecanismos para la integración de componentes, y mecanismos para la ejercitación de componentes. 18 Capitulo 3 MARCO TE6RlCO 3.3 Modelo Orientado a Objetos. El modelo orientado a objetos es una filosofia para diseñar e implenientar sistemas de software y se basa en las propiedades de: Absiracción de daros. Es un modelo de software que empaqueta una estructura de datos junto con un conjunto de operaciones asociadas a ésta, y es la propiedad que habilita el ocultamiento y encapsulado de datos. o Ellcapsulado de daros. Un objeto encapsulado es una unidad de software única con fronteras propias y bien definidas que protegen los detalles de su representación interna y con una interfaz de comunicación explícita. o Herencia. Es la propiedad de los lenguajes orientados a objetos de asumir las propiedades (atributos y comportamiento) que caracterizan a una clase de objetos denominada base a otra clase denominada derivada. Esta propiedad es la que permite la programación por incrementos, extendiendo la funcionalidad de las clases participantes en la solucción de un problema. Polimorfismo. Propiedad del comportamiento que tienen los objetos de responder de diferente manera a mensajes recibidos. El polimorfsmo se implementa a través de la sobrecarga de funciones y10 operadores y la forma se asocia en tiempo de ejecución. Este modelo apoya directamente el reuso de software ya que proporciona mecanismos que permiten adaptar un componente de código a nuevos usos o aplicaciones sin modificar su definici6n actuai. Las estructuras de programas orientados a objetos se organizan en clases taxonómicas. A mayor nivel en la jerarquia corresponde una mayor generalidad, a menor nivel en la jerarquía se incrementa la particularidad de las clases. Este es el mecanismo que proporciona el medio para hacer programación por incrementos, puesto que a mayor jerarquía las clases pueden ser reutilizadas en más aplicaciones diferentes, extendiendo su funcionalidad mediante clases más específicas. El elemento clave del modelo de programación orientada a objetos es la habilidad que proporcionan los lenguajes que soportan este paradigma para facilitar el uso de librerías de componentes reusables. Varios avances en la Ingeniería de Software hicieron más viable la reusabilidad de software, la programación orientada a objetos (POO)permitió la construcción de sistemas más generales, donde muchas partes del código puedan ser aplicadas a múltiples sistemas. 19 Capitulo 3 MARCO TEÓRICO 3.4 Lenguajes de patrones. Para el desarrollo de software los patrones son uno de 10s tÓpiCOS más nuevos que eniergen de la comunidad de desarrollo de teCnOlO@ orientadas a objetos. El arquitecto Christopher Alexander define el término patrón de la siguiente manera: Cada patrón es una regla de tres partes, el cual expresa la relación entre un cierto contexto, un cierto sistema de fuerzas (el problema) que ocurre repetidamente en ese contexto, y una cierta configuración de software (la solución) que permite que estas fuerzas se resuelvan por sí mismas[BUS96]. La meta de patrones dentro de la comunidad de software es la creación de un cuerpo de literatura que ayude a los desarrolladores de software a resolver problemas comunes y difíciles encontrados a través del proceso de desarrollo de Sohvare. Los patrones ayudan a crear un lenguaje compartido para comunicar conocimientos y experiencias acerca de problemas informáticos así como de sus soluciones. Un patrón es “un conjunto de información instructiva que captura la estructura esencial y el conocimiento de una familia exitosa de soluciones probadas a un problema recurrente que aparece dentro de un cierto contexto y un sistema de fuerzas”. Un patrón de diseño nombra, abstrae, e identifica los aspectos clave de una estructura común de diseño que la hace útil para crear un diseño orientado a objetos reusable. El patrón de diseño identifica las clases participantes y sus instancias, sus funciones y colaboraciones, y la distribución de sus responsabilidades [GAM95]. Cada patrón de diseño se enfoca en particular a un tópico o problema de diseño orientado a objetos. Describe cuando se aplica, si puede o no ser aplicado en vista de otras restricciones de diseño, y las consecuencias y negociaciones de su uso. Algunos autores definen la siguiente categoria de patrones: 3.4.1 Patrones de Arquitectura. Un patrón arquitectónico expresa una estructura de organización o esquema fundamental para sistemas de software. Proporciona un conjunto de subsistemas predefinidos, especifica sus responsabilidades, e incluyen reglas y guías para organizar las relaciones entre ellos. 3.4.2 Patrones de Diseño. Un patrón de diseño proporciona un esquema para refinar los subsistemas o componentes de un sistema de software, o las relaciones entre ellos. Comiuunente describen estructuras recurrentes de clases en colaboración que resuelven un problema de diseño en general dentro de un contexto en particular. 20 Capitulo 3 MARCO TEORICO 3.4.3 Idioms o patrones de c6digo. Un idiom es un patrón de bajo nivel, especifico a un lenguaje de programación. Un Idiom describe como implementar aspectos particulares de componentes o las relaciones entre ellos, utilizando las características de un lenguaje dado. Las diferencias entre estas tres clases de patrones esta en su correspondiente nivel de abstracción y detalle. Los patrones arquitectónicos son estrategias de alto nivel que involucran componentes a gran escala y las propiedades y mecanismos globales de un sistema. Los patrones de diseño son tácticas de nivel medio que desmenuza las estructuras y el comportamiento de entidades y sus relaciones; estas no influencian la estructura del sistema total, pero definen micro arquitecturas de subsistemas y componentes. Los Idioms son tkcnicas de programación de paradigmas y lenguajes específicos que se ajustan en un nivel bajo interno o detalles externos de la eshctura o comportamiento de un componente. Una colección de patrones forma un vocabulario para entender y comunicar ideas. Tal colección puede estar integrada junto a un todo cohesivo que revela las estructuras y relaciones inherentes de sus partes constituyentes hacia el logro total de un objetivo compartido. Esto es lo que Christopher Alexander llama un lenguaje de patrones. Si un patrón es una solución a un problema recurrente en un contexto dado por algún sistema de fuerzas, entonces un lenguaje de patrones es una colección de tales soluciones, los cuales, en cada nivel de escala, trabajan juntos para resolver un problema complejo en una solución ordenada de conformidad con las metas predefinidas. 21 MARCO TEÓRICO Capitulo 3 3.5 Gramáticas libres del conteito. Una gramática libre de contexto es un conjunto de variables cada una de las cuales representa un Icnguaje. Los lenguajes representados por las variables se describen de manera recursiva en terminos de las mismas variables, llamadas no ferminales y de símbolos primitivos llamados terminales. Las reglas que relacionan a las variables se conocen como producciones[HOP93]. Una gramática libre del contexto tiene cuatro componentes[AH090]: I . Un conjunto de símbolos ferminales. Símbolos básicos con los cuales se forman las cadenas del lenguaje. 2. Un conjunto de símbolos no terminales. Son variables que denotan conjuntos de símbolos gramaticales. 3. Un conjunto de producciones. Definen reglas gramaticales, están formadas por un lado izquierdo, unaflecha, y un lado derecho. El lado izquierdo consta de un símbolo no terminal, el lado derecho puede estar formado por símbolos terminales, símbolos no terminales, o una combinación de ambos. 4. Un símbolo inicial. Es un símbolo único y es no terminal. Una gramática libre del contexto se denota por G=(V,T,P,S), en donde : V: es el conjunto de símbolos no terminales. T: es el conjunto de símbolos terminales. P: es el conjunto de producciones. S:es el símbolo inicial. A continuación se muestra un ejemplo de una gramática que define expresiones aritméticas simples. Las producciones son: expr -+ expr op expr expr -+ (expr) expr + -expr expr 4 id op + + op -+ op + * op+I - op+? Los símbolos terminales son: id + - * I ? ( ) Los símbolos no terminales son: expr y op. El símbolo inicial es: expr. 22 Capítulo 3 hlARCO TEÓRICO 3.6 JavaCC [SüN-1. Esta herramienta se utiliza para la generación de analizadores léxicos y sintácticos (parsers), el significado de sus siglas es: Java Compiler Compiler. El funcionamiento de la misma es el siguiente: JavaCC toma como entrada un archivo con extension jj, el cual debe contener la especificación de la gramática en formato BNF del lenguaje a analizar, y postenormente genera un programa en Java (conjunto de clases) que reconoce empates a dicha gramática Los pasos para la generación del parser son: 1. Escribir el archivo que contiene la especificación de la gramática a analizar. 2. Invocar a la herramienta JavaCC para generar el programa en Java, a través de la siguiente instrucción: javacc nombre-archivo.jj 3. Invocar el compilador de Java (Javac) para crear el código ByteCode (.class) del analizador. javac nombre-archivo.java Después de esto ya se puede invocar el parser a través del nombre de la clase principal del mismo (nombre del archivo con extensión jj), para utilizarlo con un fin específico. Además de esto JavaCC también proporciona otras herramientas como: JJTree: Es una herramienta que pre-procesa una gramática JavaCC con acciones para construir firboles sintácticos. JJDoc: Convierte archivos de gramáticas JavaCC en documentos, ejemplo: archivos HTML. ,* JavaScope: JavaScope ofrece muchas métricas de cobertura basadas en código fuente, éstas nos dan una idea de como probar nuestros parsers. 23 Capitulo 4 MODELO CONCEPTUAL DEL SISTEMA Capítulo 4 MODELO CONCEPTUAL DEL SISTEMA Aquí se describe la solución adoptada para resolver el problema planteado en el primer capítulo, además se mencionan las partes que componen la misma, y su funcionamiento. Dichas partes son: Modelo canónico para representación de patrones de diseño y la herramienta para la detección automática de patrones de diseño; explicando su arquitectura, y la interfaz al usuario presentada por la misma. 24 Capítulo 4 MODELO CONCEPTUAL DEL SISTEMA De acuctdo con el problema planteado en el primer capítulo, se hizo un análisis y se llegó a la conclusión de que una forma de detectar patrones de diseño a partir de código fuente, es basarse en su estructura, es decir, encontrar en el código fuente relaciones entre clases que son comunes en los patrones de diseño; tales relaciones son: herencia, Debido a que los patrones de diseño que se agregación, asociación’, e ins~~nciación~. detectan en IPADIC++ son de los propuestos por Erich Gamma[GAh495], se tomaron en cuenta únicaniente estas relaciones ya que son las que en este libro se menciona que los patrones de diseño pueden poseer. La definición y notación de tales relaciones se describen en el apendice A. Tomando en cuenta el análisis realizado se propuso formular un modelo canónico de representación de patrones de diseño, y construir un sistema que utilice este modelo, para que a partir del análisis de la estructura de clases de un código escrito en lenguaje C++, realice un reconocimiento que permita verificar si en dicho código se encuentra una instancia de algún patrón de diseño de los reconocidos por IPADIC++, o que le falta para que lo sea. A continuación se explica el funcionamiento del modelo canónico, y posteriormente se describirá la arquitectura del sistema y su interfaz al usuario. 4.1 MODELO C A N ~ N I C ODE REPRESENTACI~NDE PATRONES DE DISENO. El modelo canónico de representación de patrones de diseño, sirve para representar la estructura de los patrones de diseño en su forma canónica. Así mismo, de este modelo se utilizan los símbolos terminales para representar las relaciones estructurales del código fuente en su fonna canónica. Cabe hacer la aclaración que las reglas de producción del modelo no se aplican para la forma canónica del código, sino que se utilizan las reglas del lenguaje nativo, en este caso C++. De manera específica el modelo consiste en una gramática libre al contexto3 en notación BNF, la cual se enuncia a continuación: Símbolos no terminales o variables: <pairon> <clase> <conjunio-dep <deli ’ La relaci6n de Asociación es similar a la de Acquaintance mencionada en el libro de Erich Gamma. 2 La relación de Inslanciocidn es similar a la de Creates mencionada en el libro de Erich Gamma. La d n para sustituir estas dos relaciones por SUS similares en español es con la finalidad de manejar todas las relaciones encontradas en los patrones de diseno en un mismo idioma. Como se mencionó, la gramática se considera libre del contexto debido al tipo de reglas de produccibn que posee. ’ 25 MODELO CONCEPTGAL DEL SISTEMA Capitulo 4 Símbolos terminales: << 8, AGREGAClON INSTANCIACION HEREDA ASOCIACION " " (espacio en blanco) Ident $cador El conjunto de producciones es: 1. <pafron> := <clase><patron> 2. <patron> := <clase> 3. <clase> := <id><conjunto-def> 4. <clase> .' = <id><HER><id><conjunto-def> 5. <conjunto-dep := <def> <conjunto -def> 6. <conjunto-d e p := <defs 7. < d e p := <coma> 8. <def > := <AGR><id> 9. <def> := <ASW><id> 1O. <def > := <NST><id> 11. < d e p := <HER><id> 12. c d e p := <fin> ._ 13. <coma> 14. <AGR> := AGREGACION 15. d N S D := INSTANCUCION 16. <HER> := HEREDA 17. < A S O 0 := ASOCLA CION ,_ la. <fin> 19. <id> := Identifieador . I 'I I, El símbolo inicial es: <patron> 26 Capítulo 4 MODELO CONCEPTUAL DEL SlSTEMA En la figura 4.1 se muestra un ejemplo en el que se ve el resultado de aplicar el modelo a la estructura de un p a t h , las consideraciones para ejecutarlo son las siguientes: Patrón de diseño --.-. I Forma del patrón . - - - canónica - . A ASOCIACION B ASOCIACION C ASOCIACION D, 9, C,D, E HEREDA B MSTANCIACION H MSTANCIACION J, F HEREDA B INSTANCIACION G INSTANCIACION I, G HEREDA C, H HEREDA C, 1 HEREDA D, J HEREDA D Figura 4.1. Resultado de aplicar el modelo a la estructura de un patrón de diseño Se toma como base la estnictura'del patrón de diseño (diagrama de clases), a partir de este se empieza a aplicar la gramática del modelo. Al elegir una clase de la estructura del patrón de diseño, la selección puede ser de manera aleatoria, es decir, en el ejemplo de la figura 4.1 se seleccionó primero la clase A pero podría haber sido la clase D o la clase J. Las relaciones encontradas en la estructura de los patrones son: Herencia, Agregación, Asociación e ínsfanciación, su definición, representación gráfica (notación OMT) y textual (en lenguaje C++) se muestran en el apéndice A. I El símbolo terminal Identijcador corresponde ai nombre de la clase. Se aplica la gramática iniciando por el símbolo inicial, se empieza seleccionado la regla de producción número I. La regla de producción número 1 se utiliza cuando existen más clases por analizar de la estructura del patrón. Por ejemplo, cuando se selecciona la primera clase de la e s b u c m del patrón de diseño. La regla de producción número 2 se utiliza cuando únicamente queda una sola clase por analizar en la estructura del patrón de diseño. En el caso del ejemplo de la figura 4.1 esta regla de producción se usa cuando se selecciona la clase J. 27 MODELO CONCEPTUAL DEL SISTEMA Capitulo 4 En la figura 4.1 se nuestra un ejemplo -en e¡ que se ve el resultado de aplicar el modelo a la estructura de un patrón, las consideraciones para ejecutarlo son las siguientes: . Patrón de diseño__-.__.__--. . . ................... canónica .. del patrón ............. -~Forma ...... . ,. A ASOCIACION B ASOCIACION C ASOCIACION D, B, C,D, E HEREDA B INSTANCIACION H INSTANCIACION J, F HEREDA B INSTANCIACION G INSTANCIACION I, G HEREDA C, H HEREDA C, I HEREDA D, J HEREDA D --. L._____ . I Figura 4. I. Resultado de aplicar el modelo a la estructura de un patron de diseño e Se toma como base la estructura del patrón de diseño (diagrama de clases), a partir de este se empieza a aplicar la gramática del modelo. e Ai elegir una clase de la estructura del patrón de diseño, la selección puede ser de manera aleatona, es decir, en el ejemplo de la figura 4.1 se seleccionó primero la clase A pero podría haber sido la clase D o la clase J. Las relaciones encontradas en la estructura de los patrones son: Herencia, Agregación, Asociación e ínstanciación, su definición, representación gráfica (notación OMT) y textual (en lenguaje C*) se muestran en el apéndice A. El simbolo terminal Idenf8cador corresponde ai nombre de la clase. Se aplica la gramática iniciando por el símbolo inicial, se empieza seleccionado la regla de producción nhnero 1. La regia de producción nhnero 1 se utiliza cuando existen más clases por analizar de la estructura del patrón. Por ejemplo, cuando se selecciona la primera clase de la estnictura del patrón de diseño. La regla de producción número 2 se utiliza cuando únicamente queda una sola clase por analizar en la estructura del patrón de diseño. En el caso del ejemplo de la figura 4.1 esta regla de producción se usa cuando se selecciona la clase J. 21 Capitulo 4 3 MODELO CONCEP'I'UAL DEL SISTEMA La regla de producción número 3 se utiliza cuando la clase seleccionada no hereda de ninguna otra clase de la estructura del patrón. En el ejemplo de la figura 4.1, cuando se seleccionan las clases A, B, C, y D. La cuarta regla de producción se utiliza cuando la clase seleccionada hereda de alguna otra clase de la estructura del patrón. En el caso del ejemplo de la figura 4.1, cuando se seleccionan las clases E, F, G, H, I y J La regla de producción número 5 se utiliza cuando la clase seleccionada relaciona (ya sea por relación de herencia, agregación, asociación o instanciación) a una o más clases de la estructura del patrón, en el ejemplo de la figura 4.1, cuando se seleccionan las clases A, E, F, G, H,I y J. La regla de producción número 6 se utiliza cuando en la clase seleccionada se va a analizar la última (o la única) relación de la clase con alguna otra clase de la estructura del patrón. La regla de producción número 7 se utiliza cuando la clase seleccionada es una clase abstracta, o es una clase que no relaciona a ninguna otra clase de la estructura del patrón de disefio; en el ejemplo de la figura 4.1, cuando se seleccionan las clases B, C, y D. En este caso en la forma canónica generada por el patrón únicamente se escribe el nombre de la clase seguida de una coma. Las reglas de producción 8, 9 y IO se utilizan cuando se encontró una relación de Agregación, Asociación, e Instanciación respectivamente, en la clase seleccionada con alguna otra clase de la estructura del patrón analizada. La regla de producción número 1 1 se utiliza cuando la clase seleccionada, hereda de más de una clase de la estructura del patrón. La regla de producción número 12 se utiliza cuando la clase seleccionada ya no tiene más relaciones con otras clases. Las reglas de producción 13, 14, IS, 16,17, 18,19, son las que contienen los símbolos terminales, y se utilizan cuando se está formando la cadena (forma canónica) generada por el modelo. Como se mencionó anteriormente el modelo aparte de generar la forma canónica del patrón de diseño, basándose en su estructura, también proporciona los símbolos' a utilizar en la forma canónica generada por el d i g o analizado (esto es realizado por el primer módulo de la herramienta, el cual se explicará más adelante). I Dichos símbolos son los terminales de la gramática del modelo: HEREDA, AGREGACION, ASOCIAC16N, INSTANCIACI6N. ''>.>, Identificador. y ". 28 MODELO CONCEPTUAL DEL SlSTEMA Capítulo 4 En la figura 4.2. se niuestra parte del árbol de derivación formado para el ejemplo de la figura 4.1, tomando como base la gramática del Modelo Canónico para Representación de Patrones de Diseño. . . <patron> <patron> <id>’ 1 <Co>junto-defi \ ... A <ASO d ‘<id> / \<conjunto defi <deb ASOCUCIÓN D’ / 9 I I I <fin> 79 66 Espacio Figura 4.2. Árbol de derivación del ejemplo ilustrado en la figura 4.1 29 MO~ELO CONCEPTUAL DEL SISTEMA Capitulo 4 4.2 ARQUITECTURA DE IPADIC++ De manera general la herramienta’ esta constituida por dos grandes módulos que son: 1i4Ódtrlo para transjorrnación del código C + + a la jornia canónica y M ó d h de reconocimiento de patrones de diseño, los cuales son ilustrados en la figura 4.3; la herramienta fue implementada en el lenguaje de programación Java, en la figura 4.4 se visualiza el diagrama de clases de la misma en notación OMT. En los siguientes apartados se explicara el funcionamiento de tales módulos. I I 4 clmd claw3 AGREGACION close.? rimer HEREDA clcwl AsoCIAClON Clmd AGREGACION clmaó MMulo paratramiomaciái del d i g o (I 18 lomu can6niui ruonwimicnto Figura 4.3. Estructura general de la herramienta I A lo largo del documento, se manejarh de manera indistinta los tkrminos “herramienta” y “sistema”, para referhe a IPADICH. 30 Capitulo 4 MODELO CONCEPTüAL DEL SISTEMA I I Figura 4.4. Diagrama de clases en notación OMT de la herramienta 31 MODELO CONCEPTUAL DEL SISTEMA Capitulo 4 4.2.1 Módulo para transformación del código C+t a la forma canónica. Este módulo es el encargado de convertir el código escrito en lenguaje C++, a SU forma canónica correspondiente. La forma canónica mencionada a lo largo del documento, es una cadena de texto que contiene los nombres de todas las clases y sus relaciones con las demás clases pertenecientes al código; las relaciones están separadas por una conia. El módulo toma como entrada el conjunto de clases en C t t , que pueden estar en uno o en varios archivos, en el segundo caso deben existir llamadas a los demás archivos, y proporciona como salida la forma canónica del código analizado. Las entradas y salidas de este módulo se visualizan en la figura 4.5. Las clases de la herramienta que pertenecen a este módulo son: mainy modulo111 del diagrama de clases de la figura 4.4. CMigo fUCnlC I Modelo dc Re resenlacita Cm6nica de &pd I MMulo para tranrfonaciái Figura 4.5. Entradas y salidas del módulo para transformar el código en C++ a la forma canónica Las restricciones de este módulo son las siguientes: Se analiza únicamente código en lenguaje C*. En esta herramienta no se verifican errores en el código analizado, por lo tanto el mismo no debe tener errores de compilación, ni ejecución. Las clases pertenecientes ai código analizado pueden estar en uno o varios archivos, con la restricción de que en el mismo archivo deben estar tanto la declaracián como la implementación de la clase. 32 MODELO CONCEPTUAL DEL SISTEMA Capitulo 4 Para reconocer relaciones de Agregación y Asociación entre clases, deben estar declarados formalmente los objetos. Esto significa que no se detectan relaciones en las que en la misma instrucción se declare y se hagan otras operaciones con el objeto. Debido a que en C++ es dificil diferenciar entre una relación de Agregación y una de Asociación, ya que la primera se puede implementar de dos formas: ya sea declarando el objeto o como un apuntador o referencia al objeto, en cambio Asociación se implementa declarando un apuntador al objeto @ara más información ver el apéndice A); cuando se encuentra una relación implementada a través de un apuntador, se considera como Asociación, si se encuentra sin apuntador es considerada como Agregación. Para realizar su función, este módulo reconoce en el código analizado los diferentes tipos de relaciones que se pueden encontrar en los patrones de diseño, Herencia, Agregación, Asociación, e Instanciación (la definición, sintaxis y representación gráfica de estas relacimes se describe eti el apéndice A), y tomando en cuenta la manera de generar la forma canónica utilizada por el modelo canónico para representación de patrones de diseño propuesto en la tesis, se genera una cadena que contiene todas las relaciones entre las clases del código (forma canónica del código). En la figura 4.6 se muestra un ejemplo en el que se visualiza el resultado de ejecutar el módulo en cuestión. El módulo también detecta la cardinalidad de relaciones, es decir, cuando objetos de una clase se relacionan más de una vez con objetos de otra; por ejemplo, si en la clase A se encuentra más de una relación de agregación con la clase B, este módulo encuentra una relación de agregación con cardinalidad n de la clase B en la clase A. El módulo, además de generar como salida la forma canónica del código analizado, también proporciona una tabla con todas aquellas relaciones detectadas en el código en las que no están involucradas clases pertenecientes a él, por esta razón, se asume que dichas relaciones se establecen con la librería de C+t, y como tales se especifican. Esto se hace tomando en cuenta que en muchas ocasiones puede implementarse una clase de un determinado patrón de diseño utilizando alguna de las proporcionadas or la librena del lenguaje. Si no se detectaran de igual manera este tipo de relaciones siempre que se intentara analizar un código en esta situación2, nunca se encontrarían este t i p de relaciones, por lo tanto, se reconocería un patrón incompleto. P ~ I Relaciones en las que una ( o mas) de las clases involucradas fuera de la librería de clases proporcionada por el lenguaje de programación. 2 Situaciones en las que se escribe una o más clases de un algún patrón de diseno, utilizando clases de la librería del lenguaje de programación utilizado. 33 Capitulo 4 MODELO CONCEPTUAL DEL SISTEMA conversión del código a su forma canónica Gabriel ASOClACION CLASE A, Otracosa A GRECACION Clase-b, Cprod HEREDA Gabriel ASOCIACION a AGREGACION a INSTANCIACION create, DproductoBO HEREDA Otra-cosa ASOCLACION a AGREGACION s I1 1 Figura 4.6. Ejemplo donde se visualizan entradas y salidas del módulo para transformacih del código C++ a la forma canónica. 34 MODELO CONCEPTUAL DEL SISTEMA Capitulo 4 4.2.2 híódulo de reconocimiento de patrones de diseíio. El módulo de reconocimiento de patrones de diseño toma como entrada la salida del módulo anterior (forma canónica generada a partir del código), realiza el análisis de la forma canónica para detectar si se encontró algún patrón de diseño. Las entradas y salidas se visualizan en la figura 4.7. En la construcción del módulo se utilizó la herramienta JavaCC para generar analizadores léxicos y sintácticos (parsers), descrita en el capítulo 3. 1 Clawl ASOClAClON , . ................<. Figura 4.7. Entradas y salidas del módulo para reconocimiento de patrones de diseño Algunas consideraciones importantes para la creación de este módulo son: Como se mencionó, es dificil diferenciar en el código una relación de Agregación y una de Asociación, para lograrlo es necesaria información semántica. A su vez, en las clases cliente de los patrones de diseño por lo regular se hace referencia a otras clases' del patrón utilizando una relación de Asociación. Por esta razón, cuando en las clases cliente se encuentra cualquiera de estas dos relaciones, se toma como si fuera una relación de Asociación. Una consideración muy importante que se tomó en cuenta en este módulo es la siguiente: una clase que pertenece a un patrón de diseño debe poseer las relaciones ' Normalmente dichas clases son abstractas, esto es para permitir un mayor grado de reusabilidad y extensibiiidad de las aplicaciones. 35 MODELO CONCEPTUAL DEL SISTEMA Capitulo 4 necesarias que la identifiquen como parte de ese patrón, pero además, Puede poseer relaciones con otras clases, no necesariamente pertenecientes al patrón; para realizar un buen análisis y detección correcta del patrón es necesario ignorar el último tipo de relaciones. Otra consideración tomada en cuenta es: una aplicación implementada utilizando un patrón de diseño, puede tener clases que no pertenecen a él, por lo tanto es necesario ignorar este tipo de clases para lograr una eficiente detección del patrón de diseño. En la figura 4.8 se muestra una estructura de clases que ilustra lo anterior. Patrón de diseño clases que se deben ignorar Figura 4.8. Clases y relaciones que se deben ignorar al analizar un código fuente Cuando se encuentra una relación de Asociación o de Agregación en una clase cliente, primero se verifica si esa clase hereda de otra, si es as¡, se considera que la relación es con la superclase y no con la subclase. Esto es debido a que una clase abstracta no se debe instanciar y, que en los patrones de diseño es bastante c o m h encontrar este tipo de clases, además de que las clases cliente de los mismos por lo reguiar hacen referencia a ellas a través de relaciones de Asociación o Agregación, pero en el código reaimente.la relación se detecta con las clases concretas y no con las abstractas. En la figura 4.9 se ilustra lo anterior. ,-----------------------, I-------------------I------------------------ I j classciiente{ i : sub*obj=newsub(); , I 'Qclasssup{ ...} ' ...) : . : class sub: sup( ......................... I I I , I I , I ,b II , 1 I I i-----------.-.----.-----l ...) j I : : , q ' I I 1 : : ; : ' ; ?.--------..-----.-.----~ Figura 4.9. Relaciones del cliente con clases abstractas y concretas 3ó Capítulo 4 MODELO CONCEPTUAL DEL SISTEMA Los pasos seguidos para la construcción de este módulo son los siguientes: I . Antes que nada se crearon las formas canónicas de cada uno de los patrones de diseño tratados en este trabajo de tesis (se muestran en el Apéndice C), apoyándose en el Modelo Canónico para Representación de Patrones de Diseño, y en la estructura de clases de cada patrón. - 2. Parte de este módulo se generó utilizando la herramienta JavaCC por lo que se creo un archivo con extensión jj, donde se especifica la gramática de 10 que se desea analizar. Para formular tal gramática, se analizó la forma canónica de cada patrón de diseño y basándose en esto, se creo la gramática de cada uno. También se analizó el funcionamiento de cada patrón, es decir, se detemiinaron los tipos de clases o relaciones que tiene, y cuales se pueden repetir para que siga siendo el mismo patrón, como por ejemplo, en el patrón Abstract Factory, puede haber n fábricas concretas (Concrete Factory), y sigue siendo el mismo patrón, la restricción es que herede de fábricas abstractas, y que cree productos. En la figura 4.10 se muestran dos estructuras de clases que obedecen al patrón Abstract Factory. ProdudoAbslrado Figura 4.10. a) Estructura mínima de clases del patrón Abstract Factory. b) Estructura genérica de clases del patr6n Abstract Factory. 31 Capítulo 4 MODELO CONCEPTUAL DEI, SISTEMA 3. Para formular ial gramática, se analizaron los tipos de clases y relaciones que posee cada patrón, y se crearon reglas de producción para cada tipo de relaciones del patrón. En el punto 7 se muestra la graniática que fue especificada en el archivo de JavaCC. 4. Después de formular la gramática de cada patrón de diseño, se creo un método (función) para cada una de ellas, es decir, uno para analizar cada patrón, además de otros necesarios para el funcionamiento del módulo, como por ejemplo, se implementó un método para revisar si una clase es subclase de otra. 5 . Después de lo anterior, se invocó a la herramienta JavaCC, para generar las clases pertenecientes al analizador. 6 . Posteriormente se invocó al compilador de Java para generar el código de bytes (Bytecode) del analizador. Después de esto, el analizador está listo para llamarse desde cualquier otra clase. 7. A continuación se muestra la gramática que fue alimentada a JavaCC para realizar el reconocimiento de patrones de diseño basándose en la forma canónica generada a partir del código. Símbolos no terminales o variables: <COMA> <AGR> <INST> <HER> <ASO0 <ID> <CARD> Símbolos terminales: I, >> AGREGACION INSTANCIACION HEREDA ASOCiACION In1 Identifirador El conjunto de producciones es: 1. < A S O 0 2. <AGR> 3. <INSP 4. <HER> 5. < C O M > 6. <CARDS 7. <ID> := ASOCUCION := AGREGACION := INSTANCIACION := HEREDA := <’,” := [n] - [,,a>,_ ,<z,,, ,_ ,<_ “z” >,_ I> > _ ‘,z <> >#_ “z” > >> v, ”0 “9 ”]) I&_ _ 38 MODELO CONCEPTUAL DEL SISTEMA Capítulo 4 -. Para las relaciones Componen/: 8. <ID><COMA> {...}I Para las relaciones Cliente: 9. ((<ID> (<MS’p<ID>)**{}’ ( ( ((<ASOC>I<AGR>)<ID><CARD>)I (<ASOC>I<AGR>)<ID>) { ...I (<INsP<ID>)*)+~{ <COMA>) {...} Para las relaciones Leaf 10. I (<ID> (<HER><ID>)+{ ...}(<ASOC><ID>)* { } <COMA>) { ...} Para las relaciones Composite: Para el uatrbn de diseño Iferafor: Para las relaciones Aggregate e Iterator: 13. <ID><COMA> {...} Para las relaciones ConcrereAggregure: 14. I (<ID> (<HER><ID>)+{ ...} ( (<AGR>I<ASOC>)<IDxCA>)*l ((<AGR>I<ASOC>)<ID>){} (<MSP<ID>)+{ ...} (( (<AGR>I<ASOO) <ID><CARD>)*I (<AGR+ASOC>) <ID>){ } I Entre las llaves de apertura y cierre con puntos suspensivos ((...I) existe código fuente. Significa que se puede repetir de O a n veces. 1 Las llaves de apertura y cierre vacias (( )) se usan para ignorar elementos. 4 Significa que se puede repetir de 1 a n veces. 39 MODELO CONCEPTUAL DEL SISTEMA Capitulo 4 <COMA>){...} Para las relaciones Coticretelterator: Para el patrón de diseño Abstract Facíorv: Para las clases abstractas (Fábricas Abstractas y Productos Abstractos): 17. <ID><COMA> {...} Para las relaciones Cliente: 18. I (<ID> (<HER>I<íNST><ID>)*{ } ( ( ((<ASOC>I<AGR>)<ID><CARD>)I (<ASODJ<AGR>)<ID>)(...} (<INST><ID>)*)+{} <COMA>) {...} Para las relaciones Fábricas Concretas (ConcreteFactary): 19. I (<ID> (<HER><ID>)+{ ...} ((<AGR>I<ASOC>)<ID>)*{ } (<INS’P<ID>)+{...} (<AGR>I<ASOC>) <ID>)* { } <COMA>){ ...} Para las relaciones Producto (Product): 20.1 (<ID> (<HER><ID>)+{...) ( (<MST+AGR>I<ASOC>) <ID>)* { ) <COMA>){ ...) Reglas que ignora: 40 MODELO CONCEPTUAL DEL SISTEMA Capítulo 4 En la figura 4.1 1 se muestra un ejemplo en el que se visualizan la entrada ai inódulo de Reconocimiento de patrones dc diseño, y la salida arrojada por el mismo. ASOCIACIdN AProductoh I r I AbstractFactory.Cfactoryl HEREDA i AbstraclFactoryMSTANCIAClbN I CProducloAO MSTANCIAClbN CProducioBO, Cfactoryi HEREDA AbstractFactory MSTANCIACIbN CProductoAl MSTANCIAClbN CLASES ABSTRACTAS: AProducloA APmductoB AbsuactFactory reconocimiento CProductoAO HEREDA AProducioA CProductoAl HEREDA AProductoA, CProductoBO HEREDA AProductoB, , I 1 1 CProductoAO CProductoBO CProductoAl I Figura 4.1 1. Ejemplo donde se visualizan entradas y salidas del módulo para reconocimiento de patrones de diseño. 41 MODELO CONCEPTUAL DEL SISTEMA Capitulo 4 4.3 JNTERFAZ AL USUARIO La herraniienta proporciona al usua muestra en la figura 4.12, ésta contiene diseño, se selecciona el patrón que se una proporciona ayuda sobre herramienta. En la figura 4.13 y un entorno gráfico, la pantalla principal se con dos menús, en el menú Patrones de el menú Ayuda, contiene dos opciones, y la otra información sobre la de tales menús. Figura 4.12. Pantalla principal de la herramienta. I Figura 4.13. Opciones del menú Patrones de diseño. 42 MODELO CONCEPTUAL DEL SISTEMA Capitulo 4 Figura 4.14. Opciones del menú Ayuda. Cuando en el menú Patrones de diseño se selecciona una opción, aparece una ventana, en la que se selecciona el archivo que se analizará en busca del patrón seleccionado, en la figura 4.15 se muestra tal ventana, Forma candnlca del paWn: IAggregate. ConcreteAggregateHEREDA Aggregate 1 Nombre del afchhu a analhar I D ~ m m V A T R O N E C V l e R 1 ~ ~ e.COD bal I Relaclones eilstentes en el t6dlgo Harator Relaclones del codigo con la librena Resunado de buscar el p&6n CV\CESABSTRACTS Agoregate Figura 4.15. Ventana para seleccionar el archivo a analizar y buscar el patrón de diseño seleccionado 43 Capitulo 4 - MODELO CONCEPTUAL DEL SISTEMA .. La figura 4.15 contiene: Un área de texto que visualiza la forma canónica del patrón de diseño elegido, Un campo de texto para escribir el nombre del archivo a analizar y 3 botones, uno para acepmr, uno para examinar el disco en busca del archivo, y otro para mostrar el código fuente del archivo seleccionado. En las figuras 4.16 y 4.17 se muestra el resultado de seleccionar los botones Examinar y Código respectivamente. Un hrea.de texto en la que se muestra las relaciones encontradas entre las clases pertenecientes al código analizado (forma canónica del código). Un área de texto que muestra las relaciones encontradas entre las clases del código analizado y la librería de C++. Un área de texto en la que se visualiza el resultado de buscar el patrón de diseño elegido en el código analizado. Figura 4.16. Resultado de seleccionar el botón Examinar. 44 Capitulo 4 MODELO CONCEPTUAL DEL SISTEMA inciude~d:lirmmi~aironesniteeralo~g9ie9ale hoo' ConcreieAggregaleOCapgregaleEnOy- -tali = O:) -ConcreleAagregateO(remme0;I Figura 4.17. Resultado de seleccionar el botón Código. Cuando en el menú Ayuda se seleEciona la opción Patrones, aparece una ventana con información referente a patrones de diseño, y si se selecciona la opción Acerca de... aparece una ventana con información de.'la herramienta. En las figuras 4.18 y 4.19 respectivamente se muestran tales ventanas. otras palabras un pab6n de alseno es la descripcidn comunlcaclón de clases yobletos que son ajustados r e s o h r un problema de diseño general en un conteiío los tdplcos callentes que erneroe de la de desarrollo de la lecnologia orlenlada a te Uene un nombre. que slm para su manelo para racllnar la a I ~ c u ~ 1 6del n pabón vla maclón que represenia. Cada patr6n describe un problema. e1 cual ocum unay b a vez en nuesbo amblente. entonces describe el núcleo e solucldn de tal rorrna que se puede uuiQar esta solucl6n n rnlii6n dewces sm hacerlo de la mlsma l o m a doswces. Figura 4.18. Resultado de seleccionar la opción Patrones del menu Avlida 45 Capitulo 4 MODELO CONCEPTUAL DEL SISTEMA entro Naclonal de Inresllgacibn y Desarolio ecnológiro (cenideo. ste producto fue concedido bajo licencia a: ng. Félukgustin Castro Espinoza MRiENCViEste pioduclo esta protegida por las leyes de derechos do autor yoiros tratados Inlernationales. Figura 4.19. Resultado de seleccionar la opción Acerca de... del menu Avuda. 46 Capitulo 5 EVALUACIÓN EXPERIMENTAL Capítulo 5 EVALUACI~N EXPERIMENTAL En este capítulo se describe la forma en la que se llevó a cabo la evaluación de la herramienta generada en este proyecto de tesis. Se enuncian las preguntas de investigación, las variables y términos de la investigación y sus definiciones, la hipótesis de investigación, la definición de los casos de estudio, los instrumentos de medición aplicados, el resumen del procedimiento en el desarrollo del experimento, los resultados de las pruebas, y el resumen de resultados. 47 Capítulo 5 E V A L U A C I ~ NEXPERIMENTAL 5.1 Preguntas de investigación. Las preguntas de investigación que fueron planteadas en la propuesta de este proyecto de tesis fueron: 1. Es posible establecer iin modelo formal de representación de patrones de diseño?. 2. i Es posible reconocer patrones de diseño directamente del código fuente utilizando un modeloformal de representacidn?. Más adelante en este documento se da la respuesta en detalle, basadas en una evaluación experimental, aunque por ahora, puedo adelantar lo afirmativo a estas preguntas, con lo cual se demuestra el éxito y la factibilidad del presente proyecto de tesis. 5.2 Variables y términos de la investigación y sus definiciones. La herramienta generada en el presente proyecto de tesis es de cierta forma de consulta, ya que toma como entrada un código fuente escrito en lenguaje C++, y analiza si en éste se encuentra inmerso algún patrón de diseño. Paul Santanu enuncia en su artículo [SAN95], una clasificación de las dimensiones de un sistema de consultas, las cuales se definen a continuación, ilustrrindose en la figura 5.1. 1. Expresividad. El poder expresivo, de un lenguaje de consulta, permite a los usuarios expresar consultas complejas sobre código fuente. Por ejemplo hay consultas que pertenecen a información Lt5xica y Sintáctica, tales como nombres de variable, referencias cruzadas, y aún los árboles de sintaxis son considerados más simples que las consultas que pertenecen a recursos de gráfos de flujo. En consecuencia, se requiere mayor poder expresivo para manejar gráfos de flujo. La información del código fuente puede venir en varios niveles de abstracción. A nivel léxico, el nombre de un identificador puede ser de relevancia. A nivel sintáctico, la forma de una función puede ser útil. A nivel estructural, puede uno desear examinar el árbol sintáctico de un procedimiento. A nivel semántico, las vistas de un flujo de datos y flujo de control pueden ser de inter& primario. En general, un alto poder expresivo ayuda a los usuarios a extraer información en niveles de abstracción más altos. Por ejemplo, para análisis léxico son suficientes los lenguajes de consulta basados en expresiones regulares. Para manejar la sintaxis y la estructura, el lenguaje de consultas debe proveer de mecanismos más poderosos, por ejemplo, para información basada en relaciones, es adecuado utilizar áigebra relacional. El soporte de la cerradura transítíva permite consultas basadas en trayectorias en el código fuente. Al extremo del espectro en esta dimensión, los lenguajes de soporte basados en máquinas de Turing permiten realizar cualquier clase de análisis computacional sobre la base de datos de un programa. 48 Capitulo 5 EVALUACIÓN EXPERIMENTAL I poder es un tópico i iportante en los lenguajes de consulta, que determinael grado de infOrmaCión q e puede ser extraido desde la base de datos del programa. E1 Poder expresivo puede ser determinado teóricamente, SU rango de valores es desde expresiones regulares hasta conipatibilidad con Turing, 2. ~40delOde cotldraf. También se le puede denominar compactacjbn, ~ ~ est una a indicación del esfuerzo requerido por el usuario, para especificar SUS consultas. L~~ lenguajes de consulta considerados buenos, permiten a los usuarios especificar una amplia variedad de consultas coniplejas fácilmente, idealmente de una forma interactiva. El sistema de consultas más simple, permite a los usuarios seleccionar las consultas desde un menú de consultas parametrizado pre-programado. En otras palabras, no hay lenguaje de consultas, todo lo que hay es una interfaz restringida, a los datos fundamentales del repositorio, proporcionada por el diseñador. Por otro lado, hay sistemas de consultas que proporcionan una interfaz a un lenguaje de programación a lo fundamental del repositorio. Esto es, un modelo de consultas procedural donde se espera que el usuario escriba programas completos para extraer la información del código fuente. El tercer modelo es un lenguaje de consultas de alto nivel el cual permite a los usuarios tanto libertad de especificación como un mecanismo de especificación de consultas relativamente fácil. La compactación de consultas se puede medir en términos del tamaño de la consulta y el tiempo tomado para especificar las consultas. 3. Riqueza del Modelo de Representación. Indica el grado de información detallada que puede ser almacenada en el modelo. El modelo más simple es el textual, donde el código del programa fuente es visto como una cadena de tokens en un archivo de texto, el cual proporciona una vista léxica del código, pero no muestra detalles internos del programa. O ver el código fuente en términos de relaciones que capUn modelo más ~ C sería 1% asociaciones entre diferentes elementos del programa. Por ejemplo, las herramientas de referencias c w d a s asocian la definición de identificadores con el uso del identificador en un progama. La vista relaciona1 de código se puede Usar efectivamente pa modelar un amplio rango de información de programas tales Como: las relaciones de Ilamador-llamado, cadenas uso-define, relaciones de composicián, rdaciones definido-en, etc. El tercero y más comprensivo modelo de datos involucra @fOS. LOS modelos gráficos de datos tales como: Arboles/gráfos de sintaxis, @fOS de dependencia y grifos de flujo-recursos, pueden acomodar mucha información de de programas de manera explícita e implícita, la cual puede ser Útil Para consultas Y análisis. Además, 10s modelos gráficos pueden agrupar en una clase 0 catego*a la información contenida en modelos relacionales. 49 Capitulo 5 EVALUACION EXPERIMENTAL Poder de expresividad Turing Compleio Relacional Comp. + cerradura iransiiiva Relacional Compleio (Algebra Relaciona/) Expresiones Regulares Modelo de consultas Figura 5.1 DIMENSIONES DE UN SISTEMA DE CONSULTAS 5.3 Hipótesis de investigación. “Es posible la identificación automática de patrones de diseño en código fuente. a través de la implementación de un modelo canónico de patrones de diseño”. Para evaluar la hipótesis de trabajo enunciada, el desarrollo de la tesis se ubica en el siguiente contexto: En cuanto al poder de expresividad esta herramienta, utiliza gramáticas libres del contexto. Con respecto al modelo de representación se clasifica dentro de los textuales. En cuanto al modelo de consultas se clasifica dentro de los procedurales. 50 Capítulo 5 5.4 Definición de casos de estudio. EVALUACIÓN EXPERIMENTAL ' La herramienta generada por el presente proyecto de tesis, se probó con un conjunto de aplicaciones codificadas en el lenguaje C++ que fueron bajados de Internet, la característica de este conjunto de programas es que a propósito fueron implementados en ellos los patrones de diseño, lo que nos sirve para probar en la herramienta la detección de los patrones correspondientes; así mismo, también se probó con una tesis de maestría desarrollada en esta institución educativa (cenidet), la cual no fue construida apegándose a ningún patrón de diseño, la cual nossirve para detectar código aproximado a patrones de diseño. 5.5 Instrumentos de medición aplicados. En el objetivo de la tesis el único parámetro medible con esta herramienta es que, utilizando el modelo canónico de representación de patrones de diseño enunciado en la hipótesis se detecten patrones de diseño cuando se debe hacerlo. Es posible que se presenten dos resultados, uno es el reconocimiento del patrón de diseño, y el otro es que no se detecten patrones, en este caso la herramienta muestra que tipo de relaciones le hicieron falta al código para corresponder al patrón de diseño buscado, lo cual le da al usuario una idea de porque no se encontró el patrón. Para tales efectos no es relevante medir otras cosas, como: tiempo de respuesta, interfaz al usuario, etc., aunque sí se trató de m a x i m i x la eficiencia de estas, ni tampoco se consideró impartante en este trabajo alguna mejora a las dimensiones citadas en la figura 5.1. Por lo tanto el insbumento de evaluación aplicado fue propiamente el sistema desarrollado en esta tesis, el cual nos sirvió para demostrar que el modelo canónico sirve para detectar patrones de diseño. 5.6 Resumen del procedimiento en el desarrollo del experimento. Antes de empezar a construir la herramienta se formuló el Modelo canónico para representación de patrones de diseño, el cual dicta las reglas del funcionamiento de la herramienta. Para más información consultar en el capítulo 4, el tema 4.1. La herramienta toma como entrada el código fuente a analizar, es analizado por el primer módulo de la herramienta', y como salida se obtiene la forma canónica del código. Para m b información consultar en el capítulo 4, el subtema 4.2.1. El segundo módulo de la herramienta2 toma como entrada la forma canónica del código generada por el primer módulo, la analiza, y detecta si se encontró algún patrón de diseño de los considerados en ella. Para realizar lo antenor, se crearon las formas I M6dulo para transfomaci6n del código C U a la forma canónica * Módulo de reconocimiento de patrones de diseno. 51 -Capitulo 5 E V A L U A C I ~ NEXPERIMENTAL canónicas de cada uno de los patrones de diseño involucrados en esta tesis, apoyándose cn el modelo canónico de representación de patrones de diseño, y en la estructura de cada patrón. Para más inforniación consultar en el capitulo 4, el subterna 4.2.2. 5.7 Resultados de las pruebas. La herramienta se probó con 12 casos de prueba, los cuales se describen a continuación: 5.7.1 Caso de prueba 1. En el primer caso de prueba se ilustran los pasos seguidos y los resultados de ellos al evaluar la herramienta en busca del patrón de diseño Abstract Factory en el código obteniii, de Internet que corresponde a dicho patrón: 1. En la figura 5.2 se muestra la pantalla de inicio de la herramienta, y se selecciona la opción de identificación del patrón Abstract Factory. Figura 5.2. Pantalla principal de la herramienta. 2. En la figura 5.3 se muestra la pantalla después. de seleccionar dicha opción, aquí se elige el archivo que contiene el código a analizar. 52 Capitulo 5 E V A L U A C I ~ NEXPERIMENTAL Forma canbnita del pabbn: IlenlACOWMNiCE apaAC0U"TmCE al, al. c f l I Nombre del aahm a analaar. I I _ .I Reiarloner Qdsiemes en ni tbdlpn i = Relaciones del rbdipo ron la libreria: Resunado de buscar el pabbn: Figura 5.3. Pantalla después de la selección de un patrón. 3. En la figura 5.4 se muestra la pantalla de respuesta al seleccionar el archivo a analizar. Forma ranbnira del pabbn: ~ l l e n l ~ ~ O ~ N T f falpCi ACOUUNTANCE E I I if, ai, cn 1 Nombre del arrhtm a matizar = Relatione$ edsienies en el C6dlüO: = RehtlOneS del c661go con la libreria. RBsUnadO de buscal el pahbn: Figura 5.4.Pantalla después de la selección del archivo a analizar. 53 Capitulo 5 EVALUACIÓN EXPERIMENTAL 4. En el apéndice C,se muestran los códigos fuentes obtenidos de Intcmet, en los que a propósito se iniplementaron los patrones de disefio. 5 . Después de seleccionar el archivo a analizar se pulsa el botón aceptar, y la herraniieiita despliega el resultado de la búsqueda de) patrón seleccionado en el código analizado. Como se visualiza en la pantalla 5.5 el resultado hie positivo, ya que la herramienta si detectó el patrón de disefio Abstract Factory. 5.7.2 Caso de prueba 2. En la segunda evaluación realizada a la herramienta, se buscó el patrón de diseño Iterator en el código obtenido de Internet, que sabemos contiene a dicho patrón. El resultado de esta prueba fue positivo, como se muestia en la figura 5.6. Nota. Con la intención de no repetir todas las pantallas de la herramienta, únicamente se mostrará la pantalla que muestra los resultados de buscar el patrón seleccionado en el código analizado. 54 Capítulo 5 E V A L U A C I ~ NEXPERIMENTAL 5.7.4 Caso de prueba 4. En el presente caso de prueba, se evalúa el comportaniiento de la herramienta al buscar el patrón de diseño Absiraci Factory en el código de la tesis de maestría toniada como prueba, ya que ésta no fue diseñada basándose en ningún patrón de diseño. El resultado de tal evaluación se muestra en la figura 5.8. Como se visualiza en la figura antes mencionada, lo único que le hace falta para encontrar el patrón son relaciones del tipo de fábricas concretas (Concrete Factory), lo que indica que dicha tesis posee un diseño aceptable. Para ver la estructura de los patrones de diseño identificados en esta tesis, y así observar el tipo de relaciones entre clases que poseen, consultar el apéndice B. I Figura 5.8. Resultado de buscar el patrón Abstract Factory, en el código no construido basándose en él. 5.7.5 Caso de prueba 5. En este caso de prueba se evaliia el comportamiento de la herramienta al buscar el patrón de diseño Composite en la tesis seleccionada para prueba. En la figura 5.9 se muestra el resultado de aplicar tal evaluación, como se visualiza no se encontró el patrón, debido a que el código analizado, no posee relaciones del tipo Component, y del tipo Leaf, que intervienen en el patrón Composite. 56 ss E Capiiulo 5 E V A L U A C I ~ NEXPERIMENTAL Figura 5.9. Resultado de buscar el patrón Composite, en el código no construido basándose en él. 5.7.6 Caso de prueba 6. En el presente caso de prueba se evalúa la herramienta al buscar el patrón de diseño Irerutor en la tesis de maestna seleccionada para prueba. En la figura 5.10 se muestra el resultado, como se visualiza no se encontró el patrón. Figura 5.10. Resultado de buscar el patrón Iterator, en el código no construido basándose en él. I Capitulo 5 E V A L U A C I ~ NEXPERIMENTAL I1 Además de las pruebas antes ilustradas, la herramienta también se probó aliiiientando como entrada los códigos obtenidos de Internet en busca de los patrones de diseño, para los que no fueron construido?.I Esto se hizo para ver cual es el comportamiento de la herramienta al buscar por ejemplo el patrón Abstract Factory, en el código del patron Composite. El resultado de estas pruebas Je muestra a continuación. I 5.7.7 Caso de prueba 7. paE6n-de diseño A&sfructFuctory .-.+ en el código que sabemos corresponde al patrón de diseño C%&Osite. <-- I_ ,-, El resultado de esta evaluación se ilustra en la figura 5.11. Como se visualiza, el I Figura 5.1 1. Resultado de buscar el patrón Abstract Factory en el código del patrón Composite. 58 Capítulo 5 EVALUACIÓN EXPENMENTAL 5.7.8 Caso de prueba 8. En el octavo caso de prueba aplicado, se evalúa el comportamiento de la herramienta al buscar el patrón de diseiío Abstract F a o o r ~ ,en el código que sabemos corresponde al patrón de diseño Iterator. El resultado del presente caso de prueba se ilustra en la figura 5.12. Como se visualiza, el resultado es que el código no posee relaciones del tipo Product, ni ConcreteFactory, par lo tanto la herramienta no encuentra el patrón buscado. Este resultado es satisfactorio ya que si analizamos la estructura de ambos patrones, nos damos cuenta de que lo anterior es verdadero. F ú n e cin6nlra del paD6n: c II ~ ~ a pei KQUUNTANCE o i a t ai, ~m 1~ ~ ~ ~ ~ ~ ~ ~ ~ e l a t l o n e sBdnenIes en el cbdlgo: Relatímes del t6dlpo can IP IIbmdI I ~ e s ~ n a ddeabuiiar 81paüún. NOedrten relaclanes Conrrpta-Fe_FacW PATRON NO ENCOWO Figura 5.12. Resultado de buscar el patrón Abstract Factory en el código del patrón Iterator. 59 Capitulo 5 EVALUACI~N EXPERIMENTAL 5.7.9 Caso de prueba 9. En el noveno caso de prueba aplicado, se evalúa el coiiiportatniento de la herramienta al buscar el patrón de diseño Composite en el código que sabemos corresponde al patrón de diseño Abstract Factory. El resultado de esta evaluación se ilustra en la figura 5.13. Como se visualiza, el resultado es que el código no posee relaciones del tipo Composite, por lo tanto la herramienta no encuentra el patrón buscado. Este resultado es satisfactorio ya que si analizamos la estruchira de ambos patrones, nos damos cuenta de que efectivamente si el patrón Abstract Factory tuviera relaciones del tipo Composite, se encontraria inmerso el patrón Composite en él. 80 Capítulo 5 EVALUACIÓN EXPERIMENTAL 5.7.10 Caso de prueba 10. En el décimo caso de prueba aplicado, se evalúa el conipominiento de la Iierraniienta al buscar el patron de diseño Cottlposite en-el código que sabemos corresponde al patrón de diseño Iterafor. El resultado de tal evaluación se ilustra en la figura 5.14. Como se visualiza, el resultado es que el código no posee relaciones del tipo Coniposite, por lo tanto la herramienta no encuentra el patrón buscado. Este resultado es satisfactorio ya que si analizamos la estructura de ambos patrones, nos darnos cuenta de que esto es verdad. Figura 5.14. Resultado de buscar el patrón Composite en el código del patrón Iterator. 61 Capitulo 5 E V A L U A C I ~ NEXPERIMENTAL 5.7.11 Caso de prueba 11. En el onceavo caso de prueba aplicado, se evalúa el comportamiento de la herramienta al buscar el patrón de diseño Iiernior en el código que sabemos corresponde ai patrón de diseño Absiract Factory. El resultado de esta evaluación se ilustra en la figura 5.15. Como se visualiza, el código no posee relaciones del tipo Concreteiterator, por lo tanto la herramienta no encuentra el patrón buscado. Este resultado es satisfactorio ya que si analizamos la estructura de ambos patrones, nos damos cuenta de que esto es verdad. Foma canbnica del patrbn: Agqieqate. ConcreteApQreoaieHEREDAIPüieüate ~ornbiedel archhn a analmr I pNebal AOREGACION ContreteFactoM AOREWION Relaclones del c64iqo con la Ilbnda Rewiia40 40 busca1 el oaebn PATRON NO ENCO-O Figura 5.15. Resultado de buscar el patrón lterator en el código del patrón Abstract Factory. 62 Capítulo 5 EVALUACIÓNEXPERIMENTAL 5.7.12 Caso de prueba 12. En el doceavo caso de prueba aplicado, se evalua el comportamiento de la herramienta al buscar el patrón de diseño llerutor en el código que sabemos comesponde al patrón de diseño Composite. El resultado de la presente prueba se ilustra en la figura 5.16. Como se visualiza, el código no posee relaciones del tipo ConcreteAggregate, ni Concretelterator, por lo tanto la herramienta no encuentra el patrón buscado. Este resultado es satisfactorio ya que si analizanios la estructura de ambos patrones, nos damos cuenta de que esto es verdad. w Readones edsbms en el tbdlgo: Relaclones dsl d d q o ron la liblorla R e w b d a 60 Duicir el p i M n No e w e 0 lslPtloneS Clases abrlnrtas NOgdnen relaclones Concreieto*pmegab No Bdrlen relarloner ConcmtBUeIalol PATRONNO E N C O W Figura 5.16. Resultado de buscar el patrón Iterator en el código del patrón Composite. 5.8. Resumen de resultados. Como se ilustra en los casos de prueba aplicados a la herramienta el comportamiento de ella fue satisfactorio, ya que detectó los patrones de diseilo cuando debió hacerlo, y cuando el &digo analizado no correspondía a alguno de ellos no lo hizo, aunque si informó que le faltaba para corresponder al patrón de diseño buscado. En el capítulo de Conclusiones se dará una explicaci6n más amplia, aunque aquí podemos adelantar que la utilización de la herramienta para los fines que fue construida es factible. 63 Capitulo 6 CONCLUSIONES Capítulo 6 CONCLUSIONES Este capítulo describe los alcances logrados en el presente trabajo de tesis, así como también se mencionan algunas mejoras y trabajos futuros relacionados con esta herramienta. 64 Capitulo 6 CONCLUSIONES 6.1 Conclusiones generales. *I finalizar el trabajo de tesis se pudo dar respuesta a las preguntas de investigación Y coniProbar la hi@teSiS planteada ai inicio del trabajo. Para la primera pregunta de investigación: LES posible establecer un nrodelo formal de representación de patrones de se puede concluir que Sí es posible establecer un modelo formal de representación de Patrones de diseño a través de un modelo canónico, el cual sirve para representar formahente las clases y relaciones que forman la estructura de los patrones. El modelo canónico corresponde a una gramática libre al contexto en la cual las clases y sus relaciones son parte de su alfabeto. Para la segunda pregunta de investigación: ¿Es posible reconocer patrones de diseño directamente del cedigo fuente ulilizando un modelo fornial de representacien? se puede concluir que si es posible reconocer patrones de diseño directamente en código fuente utilizando el modelo canónico de representación de patrones. Para lograr esto, tanto el patrón de diseño como el rbdigo se convierten a la forma del modelo canónico y luego se comparan para saber si existe una correspondencia, logrando de esta manera el reconocimiento de patrones de diseño en código. Las respuestas a las preguntas de investigación y la construcción de una herramienta que implemenia el modelo canónico de representación de patrones de diseño, comprueban la hipótesis: es posible la identificación automática de patrones de diseño en código. En particular para este trabajo de tesis se concluye que es posible la identificación automática de tres patrones de diseño de los propuestos por Ench Gamma [GAM951 en código fuente escrito en C H . En el capítulo 5 se muestran los resultados de la evaluación experimental de la herramienta. Para la evaluación se definieron 12 casos de prueba y los 12 casos resultaron 100% correctos. Los casos de prueba se definieron para detectar un patrón completo, parte de un patrón, o la falta completa del patrón en el código. Se puede concluir entonces que la herramienta detecta adecuadamente los patrones de diseño en el código fuente, detecta también cuando a un código le hacen falta relaciones para poder decir que corresponde a un patrón de diseño, y así mismo puede detectar la falta de patrones en el código. La representación de la forma canónica generada por el modelo es textual, lo cual puede veme como desventaja, ya que pudiera representarse de manera más formal por ejemplo utilizando una estructura de árbol, sin embargo, esto queda fuera del alcance del trabajo. Lo anterior nos da la pauta para concluir que este proyecto de tesis fue satisfactorio, ya que se alcanzaron los objetivos planteados al inicio, además se pudo comprobar la hipótesis y las preguntas de investigación. El presente proyecto de tesis representa un primer acercamiento para venficar si componentes de d i g o cuentan con un grado de calidad aceptable para ser incorporados a una base de componentes de software reusable, y ser posteriormente utilizados para 65 Capitulo 6 CONCLUSIONES construir otros sistemas. El grado de calidad referido es que el código coiistmido apcgándose a un patrón de diseño hereda atributos de la calidad y reusabilidad de éste; aunque el anterior paránietro no es suficiente para asegurar que un componente posee la calidad como para considerarse reusable. 6.2 Trabajos futuros. El presente proyecto de tesis representa el primer trabajo relacionado con patrones de diseño realizado en el área de Ingeniería de Software del cenidet, por esta razón, es necesario seguir trabajando en la niisma línea de investigación para complementar el actual proyecto. También la tesis puede ser el origen del desarrollo de trabajos futuros. A continuación se describe brevemente cada uno de ellos: En IPADIC++, las relaciones entre clases del código analizado y de los patrones de diseño se muestran en forma canónica y textual, se propone como un trabajo futuro el mostrar tales relaciones en alguna de las notaciones visuales, como por ejemplo U r n , OMT, o BOOCH, lo que hm'a más fácil para el usuario la interpretación del resultado; ya que confrontana de manera más legible y entendible el diseño del código analizado con la estructura de los patrones de diseño buscados. Debido a que el presente trabajo representa un primer acercamiento al área de patrones de diseño, actualmente IPADICtt detecta Únicamente 3 de ellos, uno de cada dimensión de la clasificación de patrones propuesta por Erich Gamma en su libro Design Pattems[GAM95], se propone como trabajo futuro extender la herramienta para la identificación de más patrones de diseño. o También, se propone agregar a IPADICtt la capacidad de detectar patrones de diseño propios de un dominio de aplicaciones. Esto sena bastante útil ya que una empresa puede tener sus propios patrones, por ejemplo, sí en el sector eléctrico se analizaran todos los sistemas construidos hasta la fecha, se pudieran encontrar patrones para ese dominio, es decir, si se detectan partes similares en varios de los sistemas, esa parte del sistema, potencialmente, podría ser un patrón, el cual, haciendo un análisis más exhaustivo y los ajustes necesarios, puede llegar a generar un patrón de diseño. Actualmente IPADICtc solamente analiza código en lenguaje C t t , por lo tanto, otro de los trabajos futuros propuestos, es que analice también código en otros lenguajes como Java, Visual Basic, Delphi, etc. A la fecha, IPADlCtc puede analizar código definido en uno o en varios archivos, con la restricción de que en un mismo archivo se declare e implemente la clase, se pretende a futuro eliminar tal restricción. Una restricción que presenta IPADICH es que para reconocer relaciones entre clases (Agregación y Asociación) deben estar declarados formalmente los objetos, es decir, primero debe ser creado el objeto y posteriormente hacer otras operaciones con él, se 66 Capitulo 6 CONCLUSIONES pretende eliniinar tal restricción con la finalidad de que se reconozca cualquier relación Iéxica y sintácticamente sin importar la forma o estilo seguido para crearla, es decir, reconocer relaciones en las que al mismo tiempo de declarar los objetos se estén haciendo otra operaciones con él. Como última conclusión, se recomienda el empleo de herramientas existentes como JavaCC para comparar estructuras de código ya que esto ahorra tiempo y esfuerzo en la generación automática de parsers. 67 Bibliografia [AH0901 Alfred v. Ravi Seth, Jeffrey D. Ullnian. Compiladores, principios, temicas Y herramientas. Addison Wesley Iberoamencana, S.A. 1990. [AHR95] Judith D. Ahrens, Drexel University and Computer Command and Control Company, Noah S . Prywes, University of Pennsylvania and Computer Command and Control Company, “Transition to a Legacy- and ReuseBased Software Life Cycle”, IEEE Computer, October, 1995, pp. 27-36. [BAN981 Jagdish Bansiya.”Automating Design-Pattern Identification”. Dr. Dobb’s June 1998. Journal. htt~://~w.ddi.coni/ddi/l998/1998-06/lead/lead.htni. [BRO--1 Kyle Brown. “Design Reverse-engineering and Automated Design Pattern Detection in Smalkdik”. clasic thesis. http://w~w2.ncsu.edu/eos/info/tasu~brown/t~esis2. htm. [BUR951 Margaret Bumett et al (eds). ”Visual objecl-orienledprogramming” concepts and environments, Manning Publications, 1995. PUS961 Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, and Michael Stal. A System of Patterns. John Wiley & Sons. 1996. [COO981 James W. Cooper. “User Interfaces That Vary with Your Data”. Fawcette Technical Publications, junio/julio 1998 [FOS98] Ted Foster and Hiping Zhao.”Modelig Transport Objects with Patterns”. JOOP enero de 1998. Pp. 26-32. [GAM951 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides. Design Patterns Elements of Reusable Object-Oriented Software. Addison Wesley Professional Computing Series. 1995 [HOP931 John E. Hopcroft, J e e e y D. Ullman. Introducción a la teoría de autómatas, lenguajes y computaci6n. Compafíía Editorial Continental S.A. de C.V. 1993. [JOY981 Luis Joyanes Aguilar. Programacih Orientada a Objetos. Segunda edición. McGraw Hill.1998. trn961 Christian Krgmer, Lutz Prechelt. “Design Recovery by Automated Search for Stnictural Design Patíem in Object-Oriented Software”. Working Conference on Reverse Engineering, IEEE CS Press, Monterey CA, November 8-10,1996. 68 [MAR961 [MIL95) Robert Martin. “the Open-Closed’P~inciple”.C++ report, enero de 1996. Hafedh Mili, Fatma Mili, Y Ali Mili; “Reusing Software: Issues and Research Directions”, IEEE Transactions on Software Engineering, vol,21, No. 6, june 1995. pJOV971 Gordon S. Novak Jr. “Software Reuse by Specialization of Generic Procedures through views”. IEEE Transactions on Software Engineering, vol. 23, No. 7, Julio de 1997. Pp. 401-417. [SAN941 Rene Santaolaya Salgado, “Ambiente de desarrollo para la programación visual de interfaces de usuario para monitoreo de procesos en línea”, Tesis de maeshía, cenidet, mayo de 1994. [SAN951 Paul Santanu. “Design and implementation of Query Languages for Program Databases”. Dissertation doctoral for the grade of Doctor of Philosophy (Computer Science and Engineering), University of Michigan, 1995 [SAN981 R e d Santaolaya Salgado. Propuesta de tesis doctoral “Modelo de Representación de Patrones de Código para la Construcción de Componentes Reusables”. CIC-IPN. Mayo de 1998. [SHU96] Forrest Shull, Walcélio Melo, and Victor Basili. “An Inductive Method for Discovering Design Patterns from Object-Oriented Software Systems”. Technical Report, University of Maryland, computer Science Department, MD, 20742 USA. 1996. [SPI97] Tom Spitzer, Component Architectures, DBMS, September 1997, pp. 56-66. [SUN--] Sun Microsystems.“Java Compiler Compiler”. hn~:llwww.suntest.comíJava~~~ [THO951 Dave n o m a s , Component-Based Sofmare Construction: Making the Tramition From crafr to Engineering, First Class The Magazine for Object Technology Professionals, February1 March, 1995, pp. 12-13. [WAT971 Sadakani Watanabe, Profesionalism through O0 and Reuse, IEEE J a w 1997. I I 69 Apéndice A NOTACIÓN Y DEFINICIÓN DE RELACIONES ENTRE CLASES En este apéndice se muestra la representación gráfica en notación OMT y la definición de las relaciones entre clases orientadas o objetos, relaciones como Herencia, Agregación, Asociación e Instanciación. 70 Las relaciones entre clases que comúnmente se encuentran en los patrones de diseño según el libro Design Pattems[GAM95], son: Herencia, Agregación. Asociación (Acquaintance) e Instanciación(Creates), a continuación se muestra su definición y notación gráfica. Herencia. Es una de las propiedades caractensticas de la orientación a objetos, permite a los objetos ser construidos a partir de otros objetos, su objetivo final es la reutilización, es decir, reutilizar código anteriormente desarikIiado[JOY98]. La herencia supone una clase base y una jerarquia de clases que contienen las clases derivadas de las clases base. Las clases derivadas pueden heredar el código y los datos de su clase base, añadiendo su propio código especial y datos a ellas, incluso cambiar aquellos elementos de la clase base que necesita sean diferentes. En la figura AI se muestra la representación gráfica de la relación de herencia. En la 5gura la clase Sub hereda de la clase Sup. I - - - _ _ _ _ _ _ _ _ _ _ - - _ _ _ _ _ _ _ _ _ _ I Figura Al. Representación gráfica de la relación de herencia. Agregación. La agregación es una relación que representa a los objetos compuestos. Un objeto es compuesto si se compone a su vez de otros objetos. La agregación de objetos permite describir modelos del mundo real que se componen de otros modelos, que a su vez se componen de otros modelos, tal relación se utiliza para expresar tipos de relaciones entre objetosparte-de (part-of) o tiene-un @as-a). A menudo es también llamada Composición. En la figura A2 se muestra la representación gráfica de la relación de agregación. En la figura la clase Agregado está agregada a la clase Compuesto. Figura A2. Representación gráfica de la relación de agregación 71 Asociación (Acquaintance). Una asociación es una conexión semántica entre los ohjetos de las clases en la asociación. Asociación implica que un objeto conoce de (knows of) otro objeto, es una relación más débil que'la agregación. En la figura A3 se muestra la representación gráfica de la relación de asociación. En la figura la clase Conocedor conoce de la clase Conocido. Figura A3. Representación gráfica de la relación de asociación InstanciaciÓn (Creates). Esta relación se usa parainstanciar clases con otras clases, su representación gráfica se muestra en la figura A4, en esta la clase Creadora crea objetos de la clase Creada. Figura A4. Representación gráfica de la relación de Instanciación 72 Apéndice B PATRONES DE DISEÑO RECONOCIDOS EN LA TESIS En este apéndice se muestra la información referente a los patrones de disefio reconocidos en la tesis. La estructura de los patrones se ilustra en la notación OMT. 73 Patrón de diseño Abstract Factory La intención del patrón Abstract Factory es proporcionar una interface para crear familias de objetos relacionados o dependientes sin especificar sus clases concretas. La estructura del patrón Abstract Factrory se muestra en la figura BI . FabncaAbsiracia I 1 - I' I I I I I I I Figura B1.Estnictwa del patrón de diseño Abstract Factory La forma canónica del patrón de diseño Abstract Factory obtenida al aplicar el Modelo Canónico para Representación de Patrones de Diseño es la siguiente: "client ACQUAiNTANCE apa ACQUAINTANCE ax al; cfl HEREDA af CREATES pa, apa, pal HEREDA apa" 74 Patrón de diseño Composite La intención del patrón de diseño Composite es componer objetos en estructuras de árbol para representar jerarquías de partes completas. Composite le permite a los clientes tratar objetos individuales y composiciones de objetos unifonnemente. La estructura del patrón Composite se muestra en la figura B2. Component A r‘ Composite Figura B2. Estructura del patrón de diseño Composite La forma canónica del patrón de diseño Composite obtenida al aplicar el Modelo Canónico para Representación de Patrones de Diseño es la siguiente: “client ACQUAINTANCE Component, Component, Leaf HEREDA Component, Composite HEREDA Component AGREGACION Componen~[n]” Patrón de diseíio Iterator La intención del patrón de disefio Iterator es proporcionx una fomia de acceder a los elementos de un objeto agregado secuencialmente sin exponer su representación subyacente. La estructura del patrón Iterator se muestra en la figura B3. D Aggregate I iterator I I OncreteIterator ConcreteAggregate , I I Figura B3. Estructura del patrón de diseño Iterator La forma canónica del patrón de diseño Iterator obtenida ai aplicar el Modelo Canónico para Representación de Patrones de Diseño es la siguiente: "Aggregate,ConcreteAggregate HEREDA Aggregate CREATES Concretelterator, Iterator, Concretelterator HEREDA Iterator A CQUAMANCE ConcrefeAggregate" 76 Apéndice C Códigos obtenidos de Internet, corresoondientes a los Datrones de diseño En este apéndice se muestran los archivos bajados de Internet, en los que a propósito se implementaron los patrones de diseao reconocidos en esta tesis. Aquí se muestra el código bajado de Internet correspondiente al patrón Composite. / / * * * Clase Component #include <iostrearn.h> class Component( public: ComponentO(next =NULL;) virtual void operation(void) = O; Component' getchild(void) const (rehim next;} virtual void setchild(Cornponent* next) ( n e x t = next;) virtual int compositeDetect0 (return(0);) private: Component. n e x t ; 1; //** Clase Composite #include "component.hpp" class Composite: public Component( public: Composite(int id)(-first =NULL; -identification = id;) virtual void add(Cornponent*); virtual void removeLeaf(Component*); virtual void removeComposite(Component*); virtual void operation(void); void operation(Component*); - viriual int compositeDetectO(return(I);) private: int -identification; Component' -first; 1; void Composite::add(Component*c)( c-setchild(-fint);//* ** ************ verificar *t* *I** * e * *I -fiKt = C; ) void Composite::removeLeaqComponent*c)( Component *t; i4_first = c)( first = c-getchildo; &child@); 1 else( for(t = - h i ; 1 = t-getchildO)( if(t-getchild0 =c) break; ) if(t){ t-setchild(c-getchildo); c-setchild(0); ) ) 78 void Composite::removeComposite(Component* c)( Componeni *I, 'mexi; if(c-composiieDetect0) ( for(t=((Coniposite *)c)--fint;1; t=tnext){ mext = 1-getchildí); t-setchild(0); 1 ((Composite *)c)--fint 1 . = O; I void Composite::operation(void)( if(_rirst) cout«"Composite: "«identification«~ndl; .. I void Composite::operation(Compnenl* c){ static int level = O ; Component *f; for(mt ¡=O; ¡<level; i*)( WUt<<" "; 1 c-operationo; if(c-compositeDetect){ level«-, for(l=((Composite ')c)-fmt; 1; t=t-getchildO)( operation(t); 1 level-; 1 1 It*** Clase Leaf #include "component.hpp" class Leaf: public Component( public: LeaKint id){-identification,= id;} virtual void operation(void) (u>ui«CLeaE "<<-identification<<endl;) private: int -identification; I; //**Clase Cliente #include "leaf.hpp" #include "composite.cpp" in1 main(void)( libreria a; libreria *y; 79 ... , Leaf I I =new Leaf(-I); Leaf 12 = new Leaf(-2); Leaf 13 = new Leaf(-3); Leaf 14 = new LeaK-4); Leaf LI =new Leaql); Leaf L2 =new Leaq2); Leaf L3 =new Leaf(3); Leaf L4 = new Leaf(4); Composite c l = new Composite(1); Composite c2 = new Composite(2); Composite c3 =new Composite(3); cl.add(&ll); cl.add(&12); c2.add(&13); c2.add(&14); c3.add(&L 1 ); c3.add(&L2); c2.add(&L3); c2.add(&c I); c3 .add(&c2); c3.operadon(&c3); COUt<<'<"; c2 .removeLeaf(&14); c3 .add(&M); c3.operation(&c3); COUt<< " "; c2.removeComposite(&~I); c3.operation(&c3); return(0); 80 Aquí se niuestra el código bajado de Internet correspondiente al patrón Abstract Fnctory. //*** Clase cliente #include "d:\hod I\\ConcFacl .HPP" # iiiclude "d:\hodI\\ConcFac2.HPP" #include "d:\hod I \\AProdA.HPP" #include "d:\hod I\\AProdB.HPP" void main0 ConcreteFactoryl Facto@ [email protected]; = new ConcreteFactoryl(0); AProductoA hodAO; ProdAO = FactotyWreateProductoA(0); ProdAO.F'@; AProductoB hodBO; ProdBO = FacioryO.CreateProductoB(0); PrcdBO.PN); //([email protected](O))->Prto; //([email protected](O))->Pry); ConcreteFactoryZ Factoryl Factoryl .PrtO; = new ConcreteFactoryXl); AhoductoA ProdAl; hodAl = Factoryl .CreateProductoA(I); RodAI.Pri0; AProductoB ProdBI; ProdBl = FactoryI.CreatehoductoB(1); prOdB1.pry); //(Factory1.CreatehoductA(ID->P; //(Factory1.CreatehoductB(I)PPnO; ) //Termina Main. //** Clase AbstractFactory #iíndef A-Factory #defme A-Factory class AProductoA; class AProductoB; class AbstractFactory ( public: AbsIractFactowíl .( /I Vacia ); //Termina constructor de la clase ~~~ ... vimial AhoductoA *CreatehoductA(int) = o; virtual AProductoB *CreatehoductB(¡t) = O; 1; // Termina c l a v Abshacffactory. #endif 81 Clase AproductoA #ihdef A-Producto-A #define A-Producto-A /I"' class AProducioA ( public: AProductoAO ( /I Vacía ... ); / I Termina constructor de la clase vimial void PrtO = O; }; /I Termina AProductoA. #endif I/*** Clase AproductoB #ihdef A-Producto-B #define A-Producto-B class AProductoB { public: AProductoBO ( / IVacla ... }; I1 Termina constructor de la clase virmal void PI-@ =O; }; 11 Termina AF'roductoB. #endif /it** Clase ConcreteFactoryl #ifndef C-Factory l #define CFactoryl #include <iosWam.b #include "d\\modl\\AbsFact.HPP" #include "d:\hodl\\CProdAO.HPP" #include "d:\hodl\\CProdBO.KP" class ConcreteFactoryl: public AbstractFactory { private: int Identificacion; public: ConcreteFactoryl(int ID) . [ Identificacion = I D }; 11 Termina constnictor de la clase virtual AProductoA *CreafeProductA(int); virtual AhoductoB *CreateProductB(int); vimial void Pryvoid) { oom << "ConcreteFactoryl : " << Identificacion << endl; } //Termina la hinción Prt. 82 AProductoA 'ConcreteFactory l ::CrealeProductA(ini I) 1 retum(new CProducioAO(1)); ) //Termina CrealeProductA. AProductoB *ConcreieFactoryl ::CreateProductB(intI ) . ( return(new CProducioBO(1)); ) / I Termina CreaieProductB. #endif /I*** Clase ConcreteFactory2 #ifndef C-Factory2 #define C-Factory2 #include <iosiream.h> #include "d:\\modI\V\bsFact.HPP" #include "d:\\modl\\CProdAl .HPP" #include "d:\\mod I\\CProdBI .HPP" class ConcreteFactory2: public AbrtractFactory ( private: int Identificacion; public: ConcrereFactory2(iotID) ( ldentificacion = ID, }; / I Termina constructor de la clase vimial AProductoA *CreateProductA(int); vimial AProductoB *CreateProductB(mt); vimial void Prt(void) { cout << "ConcreteFacroryZ: " << Identificacion << endl; } I/ Termina la hinci6n Prt. ); AProductoA *ConcreteFactoryZ::CreateProductA(int I) ( retum(new CProductoA I(1)); ) /I Termina CreateProductA. AProductoB *ConcreteFactory2::CreateProductB(int I) { rehim(new CProductoBl(1)); ) / I Termina CreateProductB. ' #endif 83 Clase CProductoAO #ihidef C-Producto-A0 #define C-Producto-A0 //"* #include "d:\\niod I\MProdA.HPP" class CProductoAO: public AProductoA . ( private: int -1; public: CProductoAO(int I) ( -1 = I; ); //Termina constructor de la clase vimial void Prio ( coui << "ProductoAO: " << -1 << endl; 1; ); //Termina CProductoAO. #endif //*** Clase CProductoAl #ifndef C-ProductoAl #define C-Producto-AI #include "d:\\mod I \\AProdA.HPP" class CProductoAI: public AProductOA ( private: int -1; public: CProductoAI(ht0 (-l=I; ); /I Termina wnsmcior de la clase virntal void PrtO ( wut << "ProductoAl: " <<' 1 << endi; 1; ); I/ Termina CProductoAl. #endif 84 Clase CProductoBO #ifiidef C-Producio-BO #define C-Producto-BO //"* #include "d:\imod I\\r\ProdB.HPP" class CProductoBO: public AProductoB ( private: int -1; public: CProductoBO(int I) ( -1 = I; ); I/ Termina constructor de la clase I' virtual void P@ ( cout << "F'roductoBO: " << endl; 1 ); I/ Temina CProductoBO. #endif i //*** Clase CproductoBl #ifndef C-ProductoB I #define CProducto-El #include "d:\hodl\\r\ProdB.HPP" class CProductoBl: public AF'roductoB ( private: int -i; i public: ChoductoBlíint . D. ( -I = I; ); I/ Termina consti-uctor de la clase 1 ); //Termina CProductoBl #endif 85 A continuación se muestra el código bajado de Internet correspondiente al patrón Itcrator. ll"* Clase Iterator template <class 'P class Iterator( public: virtual AggregateEntrycT>. finto = O ; virtual AgregateEntry-' next0 = O; virtual int isDone0 = O; virtual T currentltemo =O; 1; I/*** Clase Concretelterator #include "d:\\cmm\\pairones\\iterator\üterator.hpp" template <class 'P class Concreteiterator : public Iterato&{ public: Concretelterator(ConcreteAggregatee*); vimial AggregateEntryQ' fusto; virtual AggregateEntryQ* nexto; virtual int isDone0; virtual T currentltemo; private: ConcreteAggregate-. aggregate; 1; Clase Aggregate #include<iostream.hz #includeistring.h> #include<assert.h> template <class P c l a s r Iterator; template <class P c l a s s Concretelterator; template <class P c l a s s ConcreteAggregate; //*I* template <class 'P class Aggregate( friend class ConcretelteratoKP; public: virtual Iterato-' createlteratorí) const = O; ... I1 }; template <class 'P class AggregateEntry( úiend class ConcreteAggregate-; fiend class Concretelterator-, public: AggregateEnWT value, AggregateEnby-val = value; n e x t = item;} *item)( 86 T getvalue0 (returnCval);} /I*** Clase ConcreteAggregate #include "d:\kmm\\pahones\\iterator\\Aggregate.hpp" template <elass 'P class ConcreteAggregate : public Aggregate*( friend class ConcretelteratorcT>; public: ConcreteAggregateO (-agregateEnny 4oncreteAggregateO (remove0;) = -tail = O;) void insert(T); void append(T); void remove0; int removecr); int lengtho; virtual IteratoKP' createIteratort)(ret(new ConcretelteratorO);] private: A g r e g a t e E n m * -aggregateEntry; AggregateEnay** -tail; 1; SEP CENPDET DGXT CENTRO DE INFORMACION 87