1 - Cenidet

Anuncio
1
' i
3
' L
I
4
h
DGlT
SElT
SEP
/
P-2
-.&
Centro Nacional de Investigación y Desarrollo
Tecnológico
cenidet
Reconocimiento de patrones de diseño
de Gamma a partir de la forma canónica
definida en el IPADIC++
- .
TESIS
Que para obtener el grado de
Maestro en Ciencias en
Ciencias Computacionales
presenta
Patricia Zavaleta Carrillo
'L
Directores de Tesis:
M.C. Máximo López Sánchez
M.C. René Santaolaya Salgado
.'.
,...
\.
3 7 ..
Cuernavaca, Morelos
Enero de 2002
-
I,
.
.
..'
. .'
'
.
.
'
.
.
.... .
.
.
. .. . . ~
.
~
...,.
. .
,
..
.
" "'
;,..4
."I
.. . .
. 'i
Centro Nacional de Investigación y 'Desarrollo Tecnológkb'
FORMA C 3
REVISION DE TESIS
.
Cuernavaca, Morelos a 03 de diciembre de 2901
... .
'
.
Dr. Raúl Pinto Elías
Presidente'de la Academia de Ciencias Computacionales
Presente
Nos es grato comunicarle, que conforme a los lineamientos para la obtención del dado de
Maestro en Ciencias de este Centro, y después de haber sometido a revisión académica la
tesis denominada: RECONOCIMIENTO DE PATRONES DE DISENO DE GAMMA A PARTIR
DE LA FORMA CANONICA DEFINIDA EN EL lPADlC+ +, realizada por la C. PATRlClA
ZAVALETA CARRILLO, y habiendo cumplido con todas las correcciones que le fueron
indicadas, acoidamos nÓ tener objeci6n para que se le conceda la au'torización de impresión
de la tesis.
Sin otro particular, quedamos de usted.
Atentamente
La comisión de revisión de tesis
#
M.C. MAXIM
&
C.C.P.
Dr. Rodolfo A. Pazoc RangellJefe del Departamento de Ciencias Computacionales
INTERIOR INTERNADO PALMIRA S/N. CUERNAVACA. MOR MCXICO
APARTADO POSTAL SI64 CP 62050. CUERNAVACA,
TELS [73)12 2314.12 7613.18 7741.FAX173) 12 2434
- .
,>
I
SIP
Centro Nacional de Investigación y Desarrollo Tecnológico".
FORMA C 4
AUTORIZACION DE IMPRESIÓN DE TESIS
~.
7'
Cuernavaca, Morelos a 1O de enero de 2 0 2
C. PATRICIA ZAVALETA CARRILLO
Candidato al grado de Maestro e n Ciencias
en Ciencias Computacionales
Presente
.
.I
.,
.
- .. ..
~
....~ - . . ..
~
Después de haber atendido las indicaciones sugeridas por la Comisión Revisora d e la
Academia de Ciencias Computacionales e n relación a su trabajo de tesis:
RECONOCIMIENTO DE PATRONES DE DISEÑO DE GAMMA A PARTIR DE LA FORMA
CANONICA DEFINIDA EN EL lPADlC+ +, m e es grato comunicarle, que conforme a los
lineamientos establecidos para la obtención del grado d e Maestro e n Ciencias en este
Centro, se le concede la autorización para que proceda con la impresión de su tesis.
,
Atentamente
Dr. R o d o l f o d Sazos Rangel
Jefe del Depto. de Ciencias Computacionales
INTERIOR INTERNADO PALMIRA S/N. CUERNAVACA. MOR. MCXICO
APARTADO POSTAL 5-1 64 CP 62050. CUERNAVACA.
TELS. (73112 2314,12 7613.18 7741.FAX173) 12 2434
~ A L A U
na7ncrñcrl-rnnirlnt rnm my
cenidef
A mis padres Francisco ‘ y Medarda
A mis hermanos y a mi familia
A los amigos de toda la vida
y a todas aquellas personas que creyeron en mi
Agradezco a:
Dios por las bendiciones que me ha dado y porque siempre ha estado conmigo
incondicionalmente.
Mis asesores de tesis M.C. Máximo López Sánchez y M.C. René Santaolaya
Salgado por darme mucho de su tiempo y compartir conmigo sus experiencias y
conocimientos. Gracias por su sincera amistad.
Mis revisores de tesis M.C. Ohvia Fragoso Díaz , M.C. Andrea Salazar Magadán y
M.C. Reynaldo Alanis Cantú, por sus sugerencias para enriquecer este trabajo de tesis.
Mis maestros y amigos por compartir conmigo sus conocimientos y experiencias.
Mis compañeros de generación Anely, Iris, Areli, Anel, Socorro, Mario, Leone],
Hugo, David, Giovanni, Agustín, Fernando, Moisés, Antonio, Eduardo y a mis compañeros
de las áreas de electrónica, mecánica y mecatrónica por brindarme su amistad y apoyo.
Mis amigos Zulma y su familia que han sido como mi segunda familia; a Ely, Anita,
Fabian, Chely, Anely, Gaby y en general a todas aquellas personas que me han dado cariño,
amistad y apoyo en algunos momentos de.mi vida.
Cecilia y Miriam del centro de cómputo, Anita y Mario de la biblioteca, gracias por
la ayuda y amistad que me brindaron siempre.
La Secretaría de Educación Pública (SEP) por el apoyo económico que me brindó
durante mi estancia en esta institución.
Resumen
En el desarrollo de software un objetivo fundamental es la instrumentación de
métodos y técnicas que permitan producir software de calidad con un mínimo de tiempo de
desarrollo. El desarrollo de software basado en componentes es un método que permite
producir software a tiempo y mínimo costo de producción, y aumentando su confiabilidad.
Los patrones de diseño consideran arquitecturas revisadas para garantizar un mayor grado
de reuso, por lo tanto, es deseable que el diseño de un componente este basado en estos
patrones de diseño, lo cual asegura su calidad y reusabilidad.
En el Centro Nacional de Investigación y Desarrollo Tecnológico (Cenidet), se
trabaja en un proyecto relacionado con el desarrollo y administración de componentes de
software, un subproyecto dentro de este proyecto es el IPADIC++, el cual es una
herramienta que busca un mayor factor de reuso de código orientado a objetos, utilizando
patrones de diseño como plantillas que guían el proceso de mejora continua de la
arquitectura de los programas.
El objetivo principal en este trabajo de tesis es ampliar los alcances del
reconocimiento de patrones de diseño en código escrito en lenguaje C++, mediante la
implementación. del reconocimiento de la gramática completa del lenguaje ‘C++ bajo el
estándar ANSI-IS0 y la implementación del reconocimiento de otros patrones de diseño
descritos en el catálogo de Gamma et.al. [GAM951 adicionales a los considerados en el
IPADIC++.
La herramienta esta constituida por dos módulos. El primero recibe como entrada
código escrito en lenguaje C++. Este código es analizado sintácticamente, obteniéndose una
cadena de texto (forma canónica) que representa información de la estructura de clases del
código que se analiza. Esta forma canónica es recibida por el segundo módulo el cual
realiza un reconocimiento de los patrones de diseño a través del análisis de esta forma
canónica.
Hay dos posibles resultados obtenidos al analizar códigos escritos en lenguaje C++
con esta herramienta: “PATRON ENCONTRADO Ó “PATRON NO ENCONTRADO’.
De los casos de prueba realizados para evaluar la herramienta se concluye que los
resultados obtenidos fueron los esperados, de acuerdo al análisis manual que se hizo al
código fuente de los casos de prueba.
i
TABLA DE CONTENIDO
Resumen.........................................................................................................................
Tabla de contenido.........................................................................................................
Lista de figuras..................... ..:........................................................... ..;..........................
Lista de tablas .....;...........................................................................................................
, .
Glosario de terminos ....................................................................................................
i
.<
ii
:.
v
...
vi11
ix
...........................
1
.........................................
2
3
3
3
4
4
4
4
4
5
5
6
Capítulo 2. ESTADO DEL ARTE ...................1 ........;..............................
.,
2.1 Introduccion .............................................................................................................
7
Capítulo 1. INTRODUCCI~N
....................................
.,
1.1 Introduccion ..................................................................
. .
:
1.2 Antecedentes............................................................................................................
1.2.1 Sistema para identificación de patrones de diseño en código C t t................
. .,
1.3 Descripcion del problema..: .....................................................................................
.,
1.4 Propuesta de solucion..............................................................................................
1.5 Objetivos............................................ ;........................................ ;.............................
1.5.1 Objetivo general ................ ............................................................................
. .
1.5.2 Objetivos específicos............................................................... ;.....................
1.6 Metodología .................................................. ;..........................................................
1.7 Beneficios.................................................................................................................
1.8 Alcance y limitaciones...........~
.................................................................................
. r
1.9 Organizacion
del documento...................................................................................
~
2.2 Investigación de patrones de diseño implementados en el desarrollo de software .
2.3 Investigación de patrones de diseño en la reingeniería ............................................
2.3.1 Un método inductivo para descubrir patrones de diseño desde sistemas de
software orientados a objetos..................................................................................
2.3.2 Recuperación de diseño mediante búsqueda automática de patrones de
diseño estructurales en software orientado a objetos ..............................................
2.3.3 Ingeniería inversa de diseño y detección automática de patrones de diseño
en Smalltalk.............................................................................................................
2.3.4 Identificación automática de patrones de diseño...........................................
2.3.5 Comprensión de frameworks y patrones de diseño: un enfoque de
. , .
ingenieria inversa ....................................................................................................
2.3.6 Ingeniería inversa de componentes de diseño basada en patrones .................
2.4 Conclusiones............................................................................................................
8
8
9
9
10
10
11
11
12
13
..
I1
Capítulo 3 .MARCO TEÓRICO ..............................................................
..
3.1 Introduccion .............................................................................................................
3.2 Desarrollo de software basado en componentes......................................................
3.3 Modelo orientado a objetos............................................................ :........................
3.4 Lenguajes de patrones .................... 1.........................................................................
. 3.4.1 Patrones de diseno
..........................................................................................
.
.
3.5 Gramaticas................................................................................................................
3.5.1 Gramáticas libres de contexto ........................................................................
3.5.2 Gramáticas regulares ......................................................................................
3.6 Generador de parsers ................................................................................................
3.7 JavaCC.....................................................................................................................
.
I
Capítulo 4 MODELO CONCEPTUAL DEL S STEMA.....................
..
4.1 Introduccion........................................................................................................ ;....
...
4.2 Analisis del sistema ..................................................................................................
4.2.1 Análisis del IPADIC++..................................................................................
4.2.2 Estudio del parser que compila el código fuente según la gramática del
lenguaje C++ ..................................................................................................
4.2.3 Análisis de información requerida.................................................................
4.3 Arquitectura de la herramienta .................................................................................
4.3.1 Módulo para la transformación del código C++ a la forma canónica ............
4.3.2 Módulo de reconocimiento de patrones de diseño .........................................
4.4 Interfaz ai usuario .....................................................................................................
.
14
15
15
18
20
21
23
23
25
25
26
29
30
30
30
33
34
37
40
46
48
Capítulo 5 EVALUACIÓN EXPERIMENTAL.............................. .....
50
5.1 Hipótesis de investigación........................................................................................
5.2,Definición de casos de estudio.................................................................................
5.3 Instrumentos de medición aplicados........................................................................
5.4 Plan de pruebas ..............................................................................................
...........
..
5.4.1 Requisitos ambientales...................................................................................
5.4.2 Características a ser probadas ........................................................................
5.4.3 Características a no ser probadas ...................................................................
5.4.4 Especificación de entrada ...............................................................................
..
5.4.5 Especificacion de salida......................................................................... ;.......
.. de pruebas ...............................................................................
5.4.6 Identificacion
5.5 Resultados de las pruebas .........................................................................................
5.5.1 Caso de prueba 1 ............................................................................................
5.5.2 Caso de prueba 2 ............................................................................................
5.5.3 Caso de prueba 3............................................................................................
5.5.4 Caso de prueba 4 ..................................................................
.........................
51
51
51
51
52
53
53
54
54
54
55
56
58
58
59
~
...
111
5.5.5 Caso de prueba 5............................................................................................
5.5.6 Caso de prueba 6............................................................. ;..............................
5.5.7 Caso de prueba 7............................................................................................
5.5.8 Caso de prueba 8............................................................................................
5.5.9 Caso de prueba 9............................................................................................
5.5.10 Caso de prueba 10........................................................................................
5.5.11 Caso de prueba 11...............!........................................................................
5.5.12 Caso de prueba 12........................................................................................
5.5.13 Caso de prueba 13........................................................................................
5.5.14 Caso de prueba 14........................................................................................
5.5.15 Caso de prueba 15........................................................................................
5.5.16 Caso de prueba 16........................................................................................
5.5.17 Caso de prueba 17........................................................................................
5.5.18 Caso de prueba 18........................................................................................
5.5.19 Caso de prueba 19........................................................................................
5.5.20 Caso de prueba 20........................................................................................
5.6 Resumen de resultados........ ....................................................................................
59
60
61
61
62
62
63
64
64
65
66
66
67
67
68
68
69
Capítulo 6.CONCLUSIONES................................................................
70
6.1 Conclusiones generales............................................................................................
6.2 Trabajos futuros........................................................................................................
71
71
Bibliografia.....................................................................................................................
Anexo A . Patrones de diseño reconocidos en la tesis....................................................
Anexo B . Códigos correspondientes utilizados en la evaluación experimental.............
Anexo C. Funcionamiento del sistema..........................................................................
73
76
83
100
iv
Lista de Figuras
.
Descripción
No de figura
'Esquema del parser y scanner..........................................................
3.1
Página
26
3.2
Pantalla de generación del analizador: .............................................
21
3.3
Pantalla de selección de opciones para el analizador.......................
21
3.4
Pantalla de confirmacion ..................................................................
28
4.1
Pantalla principal del IPADICtt .....................................................
31
4.2
Ventana de diálogo de detección de patrones de diseño.................
32
4.3
Estructura general de la herramienta ................................................
31
4.4
Diagrama de clases de la herramienta ..............................................
38
4.5
Diagrama de clases del analizador sintáctico para ¡a gramática del
................................................
lenguaje C++...................................
39
Diagrama de clases del analizador sintáctico para la gramática de
. - .....................................................................
los patrones de diseno
39
Entradas y salidas del módulo para transformar el código escrito
en lenguaje C++ a la forma canónica ...............................................
40
4.8
Ejemplo en el que se visualizan entradas y salidas del módulo .......
45
4.9
Entradas y salidas del módulo de reconocimiento de patrones de
diseño...............................................................................................
46
Ejemplo en el que se visualizan entradas y salidas del módulo de
reconocimiento de patrones de diseño.............................................
48
4.11
Interfaz principal del sistema ...........................................................
49
5.1
Pantalla principal de la interfaz, mostrando opciones del menú
archivo.............................................................................................
56
5.2
Ventana de diálogo para abrir archivo fuente..................................
56
5.3
Pantalla después de elegir el código fuente......................................
51
5.4
Resultado de buscar el patrón de diseño abstract factory ..............
51
..
~
4.6
4.1
4.10
V
.
No de figura
Descripción
Página
5.5
Resultado de buscar el patrón de diseño composite .........................
58
5.6
Resultado de buscar el patrón de diseño iterator .............................
58
5.7
Resultado de buscar el patrón de diseño abstract factory en el
código del patrón composite .............................................................
59
Resultado de buscar el patrón de diseño Abstract Factory en el
. . del patrón iterator................................................................
codigo
60
Resultado de buscar el patrón de diseño composite en el código
del patrón abstract f a c t o v ..............................................................
60
Resultado de buscar el patrón de diseño composite en el código
del patrón iterator ............................................................................
61
Resultado de buscar el patrón de diseño iterator en el código del
patrón abstract factory ...................................................................
61
Resultado de buscar el patrón de diseño iterator en el código del
patrón composite ............................................................................
62
Resultado de buscar el patrón de diseño abstract factory en la
tesis de maestría ....................................................... :.......................
63
Resultado de buscar el.patrón de diseño composite en la tesis de
maestría ............................................................................................
63
Resultado de buscar el patrón de diseño iterator en la tesis de
maestría ............................................................................................
64
5.16
Resultado de buscar el patrón de diseño strategy ............................
65
5.17
Resultado de buscar el patrón de diseño template method .............
65
5.18
Resultado de buscar el patrón de diseño strategy en el código del
abstract factory ...............................................................................
66
Resultado de buscar el patrón de diseño strategy en el código del
iterator ............................................................................................
66
Resultado de buscar el patrón de diseño strategy en el código del
composite .........................................................................................
67
5.8
5.9
5.10
5.11
5.12
5.13
5.14
5.15
5.19
5.20
vi
.
No de figura
Descripción
5.21
Resultado de buscar el patrón de diseño temulate method en el
. .
codigo del abstractfactory ...............................................................
5.22
Página
67
Resultado de buscar el patrón de diseño template method en el
código del iterator............................................................................
68
Resultado de buscar el patrón de diseño template method en el
..
codigo del compsite.......................................................................
68
A.1
Estructura del patrón de diseño abstract factory ............................
77
A.2
Estructura del patrón de diseño composite ......................................
78
A.3
Estructura del patrón de diseño iterator...........................................
79
A.4
Estructura del patrón de diseñofactory method..............................
80
A.5
Estructura del patrón de diseño strategy .........1................................
81
A.6
Estructura del patrón de diseño template method...........................
82
c.1
Opciones del menú archivo.............................................................
101
c.2
Ventana de diálogo para seleccionar archivo con extensión cpp.....
101
c.3
Contenido de paneles después de elegir el archivo a analizar..........
102
c.4
Contenido de panel de forma canónica del código fuente si hay
error sintáctico en el archivo analizado............................................
102
c.5
Pantalla resultante al elegir un patrón de diseño a detectar..............
103
C.6
Submenú para patrones creacionales del menú detección.............
103
c.7
Submenú para patrones de comportamiento del menu detección ..
104
C.8
Submenú para patrones estructurales del menú detección .............
104
c.9
Opciones del menú ayuda ...............................................................
104
c.10
Ventana de diálogo de contenido del sistema.................................
105
c.11
Ventana de diálogo de patrones de diseño ..................................
c.12
Ventana de diálogo de acerca de.....................................................
5.23
.
.
....
105
105
vii
Lista de Tablas
3.1
Descripción
Clasificación de los patrones de diseño de Gamma .........................
Página
22
4.1
Ejemplo del contenido de las tablas de información ........................
36
No. de tabla
...
VI11
Glosario de términos
BACKDOOR. Acrónimo de las siglas en inglés de Backwards Architecture Concerned with
Knowledge Discovery of Object Oriented Relationships. Herramienta que implementa un
método inductivo para descubrir patrones de diseño desde sistemas de sofhvare orientados a
objetos.
CDZF. Acrónimo de Case Interchange Format. Es un cuerpo estándar patrocinado por EIA
(Electronic Industries Association) y el ISO, cuya misión es permitir el intercambio entre
herramientas de modelado tal como herramientas CASE. Para esto, CDIF define una
arquitectura metamodelo de 4 capas formal, formatos de transferencia y un metamodelo
que actúa como la comprensión común implícita de lo que los datos de las herramientas nos
dicen.
Cenidet. Acrónimo de Centro Nacional de Investigación y Desarrollo Tecnológico
Clase abstracta. Una clase abstracta actúa como una plantilla de otras clases. Normalmente
se utiliza como la raíz de una jerarquía de clases.
COTS (Components OffThe Shelf).- Definición de marcos de aplicaciones de caja negra o
de componentes estandarizados de vitrina.
Dinamic binding (ligadura dinámica). Sinónimo de late binding (ligadura tardía).
D P H . Herramienta que automatiza la detección, identificación y clasificación de patrones
de diseño en programas C++.
Framework. Es una aplicación “semi-completa” reusable que puede ser especializada para
producir aplicaciones a la medida.
Framework Luthier. Es una aplicación que provee soporte para la construcción de libros
electrónicos completamente integrados con las visualizaciones desarrolladas a partir de la
información coleccionada de algún programa analizado.
Forma canbnicu. La forma canónica es una forma de representación, basada en cadenas de
texto de los nombres de clases y las relaciones estructurales entre las clases de un sistema,
separadas por una coma.
Herramientas CASE. (Siglas en Inglés de Ingeniería de Sistemas apoyada por
computadora) Proporciona formas orientadas gráficamente para expresar planos, modelos y
diseños.
Hiperdocumentos. Documentos que tienen estructura de hipertexto, pero además
referencias a objetos multimediales (como sonidos, imágenes, videos).
ix
Ingeniería inversa. Es el proceso de analizar un sistema para:
a) Identificar los componentes del sistema y sus interrelaciones, y
b) Crear representaciones de un sistema en otra forma en un más alto nivel de
abstracción.
IPADZC++. Acrónimo de Sistema para Identificación de Patrones de Diseño en Código
C++. Herramienta que detecta patrones de diseño en código escrito en lenguaje C++.
KT. Herramienta que aplica ingeniería inversa a diagramas de diseño de código smalltalk
para detectar patrones de diseño.
OMT. Acrónimo de las siglas en inglés de Object Modeling Tecnique. Técnica de
modelado de objetos. Metodología orientada a objetos para el desarrollo de software.
Overloading (sobrecarga). Proceso de escribir más de una función u operador con el
mismo nombre. Las funciones deben .diferir en su lista de argumentos de modo que el
lenguaje puede identificarlas con una llamada.
Override (anular, ignorar, redefinir, Reimplantar). Se utiliza para describir la
reimplementación de los métodos en tipos objeto.
PAT. Acrónimo de las siglas en inglés Program Anaiys& Tool. Herramienta que realiza la
búsqueda de patrones de diseño en sistemas orientados a objetos.
Reingeniería. Examina los sistemas y aplicaciones de información con la intención de
reesbycturarlos o reconstruirlos de tal modo que muestre una mayor calidad.
Refacforización. "Refactorizar un software es modificar su estructura interna con el objeto
de que sea más fácil de entender y de modificar a futuro, tal que el comportamiento
observable del software al ejecutarse no se vea afectado." [FOW99].
UML. Acrónimo de las siglas en inglés Unified Modelig Language. E s una notación
(principalmente diagramática) para el modelado de sistemas usando conceptos orientados a
objetos.
X
Capítulo 1
’
INTRODUCCI~N
Capítulo 1
En este capítulo se presentan algunos puntos importantes resaltando la importancia
de la tesis en el área de la Ingeniería de Software. Se provee una ubicación acerca del
contexto en el cual se llevó a cabo la presente tesis, se describe el problema a solucionar, la
solución propuesta, los objetivos principales, la metodología seguida para resolver el
problema, así como los beneficios y alcances de la misma.
1
Capítulo 1
1.1 Introducción
INTRODUCCI~N
..
1
Uno de los objetivos más importantes be la Ingeniería de Software es el diseño e
instrumentación de métodos y técnicas que permitirán 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,
I
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.al área de desarrollo de aplicaciones de software [NOV97]
~
i
Para que los componentes sean reusables deben cumplir con las siguientes
características: que obedezcan a una arquiteckra bien diseñada, es decir, que tengan la
forma de plantillas genéricas, en las que se vea; disminuidos algunos problemas como son
las dependencias funcionales, que .dichas plantillas sean cerradas a las modificaciones y
abiertas a las extensiones [MAR96], y que además sean recurrentes, es decir, que se
utilicen frecuentemente.
Cuando existen componentes que cumplen con estas características se puede hablar
de patrones de diseño, los cuales define [GAM951 como “un conjunto de clases que
trabajan en colaboración en la solución de un problema que se presenta recurrentemente
bajo un mismo contexto, o de problemas similares; y que además han sido analizadas y
diseñadas de conformidad a las características antes mencionadas”. Si los componentes
están organizados como patrones de diseño, se puede asegurar en mayor medida su calidad
y también su reusabilidad.
i
Christopher Alexander [GAM951 define un patrón de diseño ‘como sigue: “Cada
patrón describe un problema, el cual ocurre una y otra vez en nuestro ambiente, describe
entonces el núcleo de la solución de tal forma que se puede’utilizar esta solución un millón
de veces sin hacerlo de la misma forma dos veces”.
i
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 se puede utilizar para
describir en una o dos palabras un problema de diseño, su solución y sus consecuencias. El
problema describe cuando aplicar el patrón, explica el problema y su contexto. La solución
describe los elementos que conforman el diseño, sus relaciones, responsabilidades y
colaboración. Las consecuencias son el resultado de aplicar un patrón. Estas incluyen su
impacto en la flexibilidad, extensibilidad, o portabilidad de un sistema.
I
En la actualidad, el uso de patrones de diseño se está fomentando en gran medida y
prueba de ello son los múltiples artículos encontrados en la literatura, en donde se plantea la
solución de problemas usando patrones de diseño, algunos de estos artíciilos se encuentran
en las siguientes referencias: [FOS98] [COO98].
2
Capítulo 1
INTRODUCCI~N
1.2 Antecedentes
El grupo de Ingeniería de Software del Centro Nacional de Investigación y
Desarrollo Tecnológico (Cenidet) trabaja con un proyecto llamado “Sistema de
administración de componentes de software bisado en frameworks”, en este proyecto se
propone un modelo de referencia del ciclo de ?ida de componentes reusables, así como la
construcción de sistemas automatizados, visuales e interactivos que den soporte al modelo
de referencia. La relevancia de este proyecto radica en la novedad del tema de investigación
y por el impacto económico que puede traer en las compañías desarrolladoras de software,
al contar con herramientas de administración I$e componentes de reuso que le permitan
madurar sus propios dominios de aplicaciones [SAN99]. El Sistema para identificación de
patrones de diseño en código C++ [CAS991 es un subproyecto que forma parte de este
proyecto.
1.2.1 Sistema para identificación de patrones Ide diseño en código C+t (IPADICH)
[CAS991
Se trata de un tema de tesis desarrollado en el Cenidet, dentro del cual se elaboró
una herramienta (IPADIC++) que tiene la finalidad de detectar patrones de diseño en
código fuente escrito en lenguaje C++; detecta los patrones: composite, iterator y abstract
factory. Esto lo realiza mediante la representacion del código fuente en forma canónica para
generar un modelo canónico, posteriormente realiza un mapeo entre éste y los patrones de
diseño de Gamma representados con el mismo modelo canónico, de manera que se puede
deducir si el código cuenta en su diseño con alguno de estos tres patrones, o si es parecido a
algún patrón de diseño conocido.
La herramienta consta de dos módulos que son: módulo para transformación de
código C++ y’módulo de reconocimiento de patrones. El primero transforma el código
escrito en lenguaje C++ a una forma canónica. El módulo de reconocimiento toma como
entrada la salida del módulo anterior, realiza un análisis de la forma canónica para detectar
si encontró algún patrónde diseño.
IPADICW es una herramienta que busca un mayor factor de reuso de código
orientado a objetos, extendiendo el tiempo de vida .útil’ de programas y controlando SU
evolución; utilizando patrones de diseño como plantillas que guían el proceso de mejora
continua de la arquitectura de estos programas.
1’
La desventaja principal es que no considera toda la sintaxis del lenguaje C++; por lo
que el código de entrada debe tener la estructura sintáctica que reconoce la herramienta y
no otra estructura bien formada, de acuerdo a las!reglas gramaticales del lenguaje C++.
1.3 Descripción del problema
El problema encontrado en el iPN)IC+i es que no considera toda la sintaxis del
leguaje C++ y solo mapea 3 patrones de diseño aei catálogo de Gamma et.al.[GAM95], ya
que en el desarrollo de IPADIC++ se consideró solo la gramática parcial necesaria para
poder implementar estos patrones. Esta restricción afecta al alcance del objetivo propuesto.
3
Capítulo 1
INTRODUCCI~N
1.4 Propuesta de solución
La meta principal de este trabajo de tesis es contribuir en la solución del problema
mencionado anteriormente, a través de lo siguiente:
Se propone la implementación completa de la gramática del lenguaje C++ bajo el
estándar ANSI-IS0 en el sistema, así como incluir dentro de la descripción de los patrones
de diseño su intención que conlleva la implementación del mismo, para distinguir la parte
racional detrás de los patrones que así lo requieran, tal como el strategy y state que tienen la
misma estructura, pero los diferencia su intención.
1.5 Objetivos
1.5.1 Objetivo general
Validar la hipótesis: “Esposible la identzjkación automática de patrones de diseño
en código fuente de la sintaxis completa del lenguaje C++, a través de la implementacion
de un modelo de representación canónica tanto de patrones de diseño como de código
fuente a analizar”.
1.5.2 Objetivos específicos
I. Construcción de un sistema que permita identificar en un código fuente escrito en
C++, 6 patrones de diseño.
2. Implementar la totalidad de la gramática del lenguaje C++ en el IPADIC++
3. Reconocer al menos 3 patrones de diseño adicionales a los propuestos en el
IPADIC++, que son:factory method, strategy y template method.
4. Incluir dentro del reconocimiento de patrones de diseño de Gamma la identificación
de la parte racional detrás del patró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 cenidet.
1.6 Metodología
La metodología adoptada para abordar el problema planteado es la siguiente:
I . Análisis de la estructura e intención de los patrones de diseño a implementar para
poder determinar la forma canónica que permita la representación del patrón de
diseño. Está forma canónica será realizada mediante el uso de la teoría de las
gramáticas libres de contexto.
4
Capítulo 1
INTRODUCCI~N
2. Análisis de la estructura y diseño del IPADICtt-.
3. Análisis e implementación de la gramática completa del lenguaje C+t dentro del
sistema, para poder transformar cualquier tipo de código escrito en lenguaje C++
bajo el estándar ANSI-IS0 a la forma canónica, basándose en el paradigma de la
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 funcionalidad de los patrones de diseño que intervienen en la tesis.
4. Diseño e implementación de un módulo de reconocimiento para los patrones de
diseño. En este módulo se hace uso de un generador de analizadores sintácticos
(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.
5. Se utiliza para la codificación de la herramienta el lenguaje de programación Java,
ya que proporciona la ventaja de ser independiente de la plataforma de hardware y
sistema operativo utilizado para ejecutar el sistema.
1.7 Beneficios
Proporcionar un avance al conocimiento formal de los patrones de diseño.
Obtener un sistema IPADIC++ más completo, que tenga la posibilidad de
reconocer un patrón de diseño en cualquier forma que pueda presentarse el código
en C++, debido a que tendrá implementada toda la gramática del lenguaje
correspondiente.
1.8 Alcances y limitaciones
El proyecto de tesis abarca lo siguiente:
Pruebas de la estructura canónica de los tres patrones de diseño que fueron
implementados en el IPADIC++ (abstract Factory, Composite, e Zterator).
Se forma la estructura canónica de otros tres patrones de diseño (factory method,
Strategy y Template method).
Implementación del reconocimiento de los patrones de diseño strategy y template
method, el patrón de diseñofactory method por razones de tiempo no se implementó
en la herramienta.
Implementación de la gramática completa del lenguaje C++ en el módulo de
transformación del código fuente, a su correspondiente forma canónica.
Desarrollo e implementación del módulo de reconocimiento de los patrones de
diseño involucrados.
Análisis de código en lenguaje C++.
Las clases pertenecientes al código analizado pueden estar en uno o en varios
archivos, con la restricción de que al presentarse en el mismo archivo deben estar
tanto la declaración como la impiementación de la clase.
5
Capítulo 1
INTRODUCCI~N
1.9 Organización del documento
La documentación del desarrollo de este trabajo de^ tesis esta organizado de la
siguiente manera:
En el capítulo 2 se'describe el estado del arte en tomo al trabajo de tesis, se
mencionan y analizan los trabajos relacionados, además se hace una comparación entre
tales trabajos y la investigación a desarrollar para observar ventajas y desventajas.
En el capítulo 3 se mencionan y explican aquellos fundamentos teóricos que
sustentan este trabajo de tesis.
En el capítulo 4 se describe la arquitectura del sistema, así como el funcionamiento
del mismo.
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 las posibles mejoras y trabajos que se le pueden realizar en el futuro.
6
Capítulo 2
ESTADO DEL ARTE
Capítulo 2
.
/
ESTADO DEL ARTE
En este capítulo se presenta el estado del arte actual en tomo a la investigación de
los patrones de diseño y se describen diferentes investigaciones en las que se incluyen
herramientas que implementan métodos para poder realizar el reconocimiento de patrones
de diseño en programas escritos en algún lenguaje de programación y se mencionan las
ventajas y desventajas de cada una de estas herramientas.
7
Capitulo 2
ESTADO DEL ARTE
2.1 Introducción
Uno de los tópicos más recientes dentro de la ingeniería de software es el término
patrones de diseño. De los trabajos relacionados a este tema se tienen varios enfoques,
entre los que hay dos direcciones principales; una de ellas se enfoca a la implementación de
patrones de diseño en el desarrollo de aplicaciones de software, ya sea incluyendo los
patrones de diseño como parte de los lenguajes de programación o implementados como
parte del diseño de la aplicación. Por otra parte, la investigación de la reingeniería acerca de
patrones de diseño, se enfoca a dos áreas: una de ellas se refiere a la identificación de
patrones en códigos existentes y la otra es aplicar métodos de refactorización para incluir
patrones en los sistemas, con el fin de poder obtener componentes reusables de estos
sistemas y poder incluirlos en frameworks o marcos de aplicaciones, orientados a objetos
donde se puedan controlar, evolucionar y administrar estos componentes.
2.2 Investigación de patrones de diseño implementados en el desarrollo de
software
Dentro de este enfoque existen varias investigaciones, como los trabajos
desarrollados por F.J. Budinsky et. al. [BUD961 quienes desarrollaron una herramienta que
automatiza la implementación de patrones de diseño; esto es realizado al proporcionarle al
sistema algunas piezas de información, nombres de aplicación específicos para los
participantes en un patrón, se crea la declaración y definiciones de clases que implementan
el patrón; posteriormente, el usuario tiene que adicionar este código al resto de la
aplicación.
Otra investigación esta enfocada a la inclusión de patrones de diseño como lenguaje
de construcción, donde Jan Bosh de la Universidad de Kariskrona I Ronneby [BOS98]
presenta un modelo de objeto'en capas, que provee un lenguaje de soporte para la
representación explícita de los patrones de diseño en el lenguaje~deprogramación.
En otro enfoque, se utilizan los patrones de diseño ya existentes para .solucionar
nuevos problemas, como describen Ted Foster y Hiping Zhao [FOS98] en el modelado de
un sistema de transportes, donde utilizan patrones de diseño que proveen un formalismo
para capturar componentes concurrentes, frecuentemente dentro de los modelos de
transportes público.
En un estudio muy particular, Baumgartner, Laufer y Russo [CHAOO] analizaron
patrones de diseño desde muchas fuentes, e identificaron pocas Características clave que
podnan adici0narse.a C++ para hacer los patrones de diseño más fáciles de expresar
(interesantemente) todas estas características del lenguaje están presentes en algunos
lenguajes.
Otras investigaciones han analizado patrones de diseño y han propuesto más clases
especializadas de características de lenguaje, con el fin de soportar más limitados
subconjuntos de patrones.
8
Capítulo 2
ESTADO DEL ARTE
2.3 Investigación de patrones de diseño en la reingeniería
Dentro de este enfoque se trata la recuperación de los patrones de diseño en
sistemas de software existentes, esto es con el fin de obtener un mejor entendimiento de los
sistemas y poder hacer de ellos una base de componentes que tengan las características
necesarias para que puedan ser reusados. Así tenemos diferentes investigaciones que se
describen a continuación:
2.3.1 Un método inductivo para descubrir patrones de diseño desde sistemas de
software orientados a objetos [SHU96]
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 denomina 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 desarrolladores para ver si cxiste algún significado en el conjunto de
clases identificadas. Este método consta de 6 pasos secuenciales e iterativos:
1. Revisión de la documentación de la especificación del problema v 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 preliminar del sistema desde la declaración de clases. Aquí
se descubre como interacttí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 implementació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 arquitectura del sistema, identificar candidatos
potenciales a patrones basados en herencia y lipas de comunicación entre clases. Este
paso se enfoca a relaciones interesantes en las arquitecturas, buscando similaridades
estructurales recurrentes. Relaciones como: clases “mediador”, “interfaz a otras clases”,
“herencia paralela”, “liga entre dos subsistemas”.
5 . Analizar los candidatos a patrones detectados en el paso 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.
6 . Intervención de diseñadores e implementadores para aclarar problemas de diseño. En
este paso se tienen entrevistas con los diseñadores y codificadores responsables para un
’
Se le denomina inductivo, ya que primero localiza patrones de diseño potenciales, posteriormente realiza
una comparación de ellos con los patrones de diseño existentes con la finalidad de hacer una mejor detección,
además si encuentra patrones nuevos, los anexa al conjunto de patrones de referencia.
9
Capítulo 2
ESTADO DEL ARTE
mejor entendimiento 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.
Su principal desventaja es que se trata de un método manual, por lo tanto requiere
de mucha intervención por parte del usuario.
2.3.2 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 (Program Análisis
Tool), 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 Erich Gamma
[GAM95], los cuales son: adapter, Bridge, Comporite, Decorator y Proxy.
Los pasos que sigue PAT para la búsqueda de patrones de diseño son:
1. Cada patrón es representado como un diagrama 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
C++ 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 de este sistema 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 patrones de creación y de comportamiento.
2.3.3 Ingeniería inversa de diseño y detección automatica de patrones de diseño en
Smalltalk [BR097]
En este artículo Kyle Brown describe el desarrollo de su tesis de maestría, en la que
demuestra la viabilidad de desarrollo de programas para detectar el uso de patrones de
diseño de software en programas realizados en lenguaje Smalltalk. Para este fin examina la
estructura de los patrones de diseño, determina la naturaleza de lo que hace que un patrón
de diseño se detecte por medios automatizados y bosqueja algoritmos por medio de los
cuales un pequeño conjunto de patrones de diseño pueden ser detectados.
10
Capítulo 2
ESTADO DEL ARTE
Esta tesis documenta el desarrollo de una herramienta de software (KT) la cual
recupera información de diseño desde código Smalltalk, y la usa para detectar algunos
patrones de diseño 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.
La desventaja de esta herramienta es que no identifica patrones de creación.
2.3.4 Identificación automática de patrones de diseño [BAN981
En este artículo se presenta una herramienta (DP++) 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 por Erich Gamma et.al. [GAM95]. 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
referenciaíapuntador 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, es que no detecta patrones de diseño de
creación (creational patterns).
2.3.5 Comprensión de frameworks y patrones de diseño: un enfoque de ingeniería
inversa [CAM971
Se trata de una investigación basada sobre el framework Luthier, para desarrollar
herramientas para aplicación de análisis y visualización por el significado de técnicas de
reflexión basadas sobre meta-objetos. Luthier provee soporte flexible para proporcionar
herramientas de visualización adaptables para diferentes funcionalidades de análisis,
usando un manejador de hiperdocumento para organizar la información. Una vez que una o
muchas aplicaciones son desarrolladas en un framework dado, son analizadas, se reúne una
representación prolog de dato y es usada para reconocer potenciales patrones de diseño que
pueden existir en el diseño del framework. Prolog es usado para representar las reglas de
reconocimiento de patrones de diseño, para desarrollar las visualizaciones de patrones
potenciales y para generar explicaciones acerca de estos patrones y las razones que sugieren
su presencia en el diseño. Reconoce patrones como el composite, decorator, proxy, state y
strategy.
Para probar la efectividad de la investigación y la herramienta, un experimento
sobre utilización delframework se llevó a cabo. El experimento no precisamente demostró
ESTADO DEL ARTE
Capítulo 2
el nivel de eficiencia del enfoque dc comprensión delfrurnework ni de las herramientas de
desarrollo para soportarlo, pero dan una buena idea de sus ventajas y limitaciones.
Su principal desventaja es que no reconoce patrones de creación y no demuestra una
buena eficiencia de la herramienta.
2.3.6 Ingeniería inversa de componentes de diseño basada en patrones [KEL99]
Es una investigación con enfoque principal a la recuperación de información
referente a lo racional detrás de las decisiones del diseño de grandes sistemas de software.
Aquí se presenta un medio ambiente para la ingeniería inversa de componentes de diseño
basado en las descripciones estructurales de patrones de diseño.
El medio ambiente consiste del siguiente conjunto de técnicas y herramientas:
1. Capturar código fuente. El propósito es extraer un modelo inicial del código fuente
existente que esta escrito en C++. Se genera una representación basada en ASCII de los
elementos relevantes de código. Se adopta el formato transferido CDIF como la sintaxis
y el metamodelo UML así c o h o el modelo semántico.
2. Repositorio de diseño. Su propósito es proveer un almacenamiento centralizado,
manipulación y consulta de los modelos de código fuente. El esquema del repositorio de
diseño es basado sobre el metamodelo UML extendido. El sistema administrador de
base de datos orientado a objetos Poet 5.1 sirve como repositorio.
3. Recuperación de diseño basada en pufrones. El propósito es ayudar a estructurar partes
de diagramas de clases para reensamblar diagramas de patrones. Hay 3 técnicas para
soportar esta tarea:
Recuperación automática. .
Recuperación manual.
Recuneración semi-automática.
La recuperación automática, relaciona a la estructura automatizada completa de diseños de
software acorde a la descripción de patrones, los cuales son almacenados en el repositorio
como componentes abstractos de diseño.
4. Representación de diseño. Su propósi.to es proveer la visualización interactiva y
refinamiento de modelos de código fuente, componentes de diseño abstracto y
componentes implementados.
Se aplicaron pruebas sobre 3 sistemas industriales, de los que 'se seleccionaron los
componentes de diseño abstracto que están basados en la descripción de los patrones de
diseño templute method, fuctov method y bridge. De las pruebas aplicadas al medio
ambiente se concluye que como las estructuras del template method y factory method
reflejan en su estructura la intención del patrón respectivo se puede contar con que la
recuperación en los componentes de diseño de: ambos patrones es correcta, mientras que
para el patrón bridge requiere de juicio humano, ya que se trata de un patrón que puede ser
implementado en muchas diferentes maneras.
'
'
Su principal desventaja es que depende de varias herramientas para ejecutarse.
12
Capítulo 2
ESTADO DEL ARTE
2.4 Conclusiones
La mayor parte de las herramientas descritas anteriormente solo consideran algunos
de los patrones de diseño de Gamma, principalmente de comportamiento o estructurales y
solo algunos de creación, lo que podria deberse,a que aún no se ha podido encontrar un
método adecuado para identificar patrones de diseño que tienen estructura idéntica, además
difieren en la intención que conlleva el uso de tal patrón. Por otra parte, también se
encuentra que existe dentro de la identificación de patrones de diseño en código fuente, otra
dificultad que se relaciona con la manera de programar, de los desarrolladores de software,
ya que existen dentro de los códigos implementaciones iguales con diferente estructura
sintáctica [FUC90].
Además, la mayoría de las herramientas descritas anteriormente 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. El.IPADIC++ se desarrolló en
lenguaje Java, lo que le permite poder ejecutarse en prácticamente cualquier plataforma y
sistema operativo que soporte Java, la desventaja de IPADIC++ es que no implementa la
gramática completa del lenguaje C++, por lo que no reconoce patrones de diseño que no
estén implementados con la estructura sintáctica parcial que reconoce en sus módulos.
13
Capítulo 3
MARCO TEÓRICO
Capítulo 3
MARC~OTEÓRICO
En este capítulo se describen las bases teóricas que dan fundamento al desarrollo de
está investigación, tratando aspectos como: desairollo de software basado en componentes,
el modelo orientado a objetos, lenguajes de patrones, patrones de diseño, gramáticas libres
de contexto, gramáticas regulares y la herramienta para generación de analizadores léxicos
y sintácticos (parsers) JavaCC.
14
Capítulo 3
MARCO TEÓNCO
3.1 Introducción
En el contexto del desarrollo de esta tesis se encuentran algunos fundamentos
teóricos, de los cuales es importante indicar su relación con este trabajo ‘de investigación,
asi como describirlos brevemente.
Este tema de investigación se encuentra inmerso en el área de Ingenieria de
Software, en la línea de investigación de desarrollo de sofhvare basado en.componentes,
dentro de la cual la investigación relacionada con los patrones de diseño ayuda en cierta
forma, a determinar si un software cumple con. las características para ser reusable y ser
incorporado a una base ‘decomponentes.
El contexto de relación del modelo de desarrollo orientado a objetos con esta tesis,
es que los patrones de diseño emergen del modelo de desarrollo orientado a objetos, por lo
tanto es necesario dar una descripción de este modelo. Además de que el IPADIC++
analiza código escrito en lenguaje C++ el cual obedece al paradigma orientado a objetos.
Asimismo, el lenguaje Java utilizado para la codificación de la herramienta esta basado en
el modelo de desarrollo orientado a objetos.
Este trabajo realiza la detección de patrones de diseño, a partir del análisis de código
fuente, por lo que es necesario comprender y analizar los patrones de diseño y su relación
con los lenguajes depatrones.
La relación de las gramúticas 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 de contexto dado el tipo de reglas, que :posee. Por otra parte, para
especificar la sintaxis en la gramática del lenguaje C++ se~implementauna gramática
regular.
Para la generación de los analizadores utilizados por los módulos implementados, se
utilizó la herramienta Javacc para la generación de analizadores léxicos y sintácticos, por lo
que se da una breve descripción del funcionamiento de esta he&amienta.
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
inicio a medida que los sistemas de software evolucionaron pasando de la etapa en que el
software se diseñaba a la medida de cada aplicación y tenía una distribución relativamente
pequeña. La segunda etapa se caracterizó por la multiprogramación, los sistemas
multiusuario y la introducción de nuevas formas de interacción hombre-máquina, en esta
etapa el software se desarrollaba para distribuirlo ampliamente; conforme crecía el número
de sistemas de software se extendieron las bibliotecas de computadora, los productos de
software incorporaban cientos de miles de sentencias en las que se presento la necesidad de
realizar actividades de “mantenimiento de software”, estas actividades comenzaron a
absorber recursos de manera alarmante y la naturaleza personalizada de la mayona de los
programas los hacía imposibles de mantener, lo que dio origen a la crisis del software. La
cual se ha traducido en la insatisfacción a la demanda de aplicaciones informáticas. Si bien
Capítulo 3
MARCO TEÓRICO
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 de desarrollo de sistemas, una meta
actual de investigación en ingeniería de software es la de otorgar,,facilidadesen los procesos
por 'medio de la adopción de herramientas automatizada: para construir, entender, mantener
y documentar el software, conduciendo a una mejor calidad y confiabilidad, así como una
mayor satisfacción del cliente [AHR95].
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 movimiento hacia
componentes de software está siendo manejado, por la urgente necesidad de contar con
artefactos de software reusable que cuenten con una mejor calidad y que puedan ser
configurados 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 (API'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 ingeniería 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 librerías 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 subrutinas 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 y/o
módulos compuestos que logran una mayor funcionalidad, "para dar satisfacción a los
requerimientos de nuevas aplicaciones.
El modelo de programación orientado a objetos tienda tecnología con el potencial de
incrementar el reuso de componentes de software, al nivel de objetos, porque con orientado
a objetos existe un plan, denominado clase o plantilla, para la creación de objetos, el cuál
empaqueta las estructuras de datos (estado) con las funciones (comportamiento)
relacionadas a éstas e indica el espacio en memoria necesario para almacenar el estado y
sus valores iniciales, y se facilita un mecanismo para la construcción de las instancias. El
elemento clave en este modelo es la habilidad que proporcionan los lenguajes que soportan
este paradigma para facilitar la reutilización de bibliotecas de clases. .
16
Capítulo 3
MARCO TEÓFUCO
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
más 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 a objetos, la otra dirección va hacia la definición de
componentes de anaquel (COTS) que utilizan un modelo de infraestructura común.
Un framework es 'un conjunto semi-completo de clases en colaboración que
incorpora un diseño genérico el cual puede ser adaptado a una variedad de problemas
específicos para producir nuevas aplicaciones hechas a la medida [JOH98] y [FAY97]. 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 proporcichando 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 negras, blancas o grises. 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 algoritmos propietarios y, la estructura que pudieran
impactar en la evolución delframework o su portabilidad. Los artefactos de reuso de este
paradigma lo representan las diferentes configuraciones o comunidades de clases
interactuando
.y organizadas en jerarquías de herencia denominados frameworks. Por otro
.I
ladg; trabajos recientes presentan a los patrones como un método promisorio 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 futuro se vislumbra que
este enfoque 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,
I
17
Capítulo 3
MARCO TEÓRICO
estos componentes se empacan en formato de solo ejecución y, tal vez, con algo de código
fuente como documentación [TH095]. Aunque muchos componentes son implementados
como objetos, un componente no tiene que ser un objeto. Un componente solo necesita
empacar la hncionalidad de programas de tal forma que las capacidades del componente
sean 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
componentes para ampliar el acceso a los datos que ellos manejan [SPI97].
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, tales
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,
transitando desde los tradicionales modelos de cascada a los modelos más modernos como
el de prototipos rápidos, implementados con interfaces interactivas que permiten producir
software 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 construcción de
sistemas basándose en el uso de éstos. Margaret Burnett [BUR951 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.
3.3 Modelo orientado a objetos
El modelo orientado a objetos es una filosofía para diseñar e implementar sistemas
de software, que permite una representación más directa del modelo del mundo real en el
código. Este modelo se soporta en cuatro propiedades básicas: “abstracción de datos ”,
“ocultación de datos ”, “herencia y ‘)olimorfismo” y en cinco componentes: “clases“,
“objetos’’, “métodos”, “mensajes” e “instancias ”:
”
Abstracción de datos. 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. La abstracción de datos es representada por la
18
Capítulo 3
MARCO TEÓRICO
“descripción del protocolo .de la clase”, este protócolo define las propiedades de
cualquier objeto que sea instancia de la clase.
Ocultación de datos. La implantación interna. de los objetos que dan los detalles de su
funcionamiento, debe estar protegida. Es decir, los datos ocultos del objeto Únicamente
I
deben ser accesibles por los métodos propios del objeto.
81
Herencia. Es una propiedad clave en la programación orientada a objetos. Una subclase
Y hereda todos los atributos y operaciones asociadas con su superclase X. Esto
significa que todas las estructuras de datos y algoritmos originalmente diseñados e
implementados para X están inmediatamente disponibles para Y . Cualquier cambio en
los datos u operaciones contenidas dentro de una superclase se heredarán
inmediatamente por todas las subclases que se derivan de la superclase [PRE98].
Polimorfismo. Propiedad del comportamiento que tienen los objetos de responder de
diferente manera a mensajes recibidos. El polimorfismo se implementa a través de la
sobrecarga de funciones y/o operadores y la forma se asocia en tiempo de ejecución.
Clases. Es un concepto orientado a objetos que encapsula las abstracciones de datos y
procedimientos que se requieren para describir el contenido y comportamiento de
alguna entidad del mundo real [PRE98]. La clase, define lalplantilla o el protocolo para
la creación de objetos semejantes, y al .mismo tiempo conceptúa una entidad.
Objetos. El objeto encapsula datos (los valores de los atributos que definen el objeto),
operaciones (acciones que se aplican para cambiar los atributos del objeto), otros
objetos (pueden definirse objetos compuestos), constantes (fijar valores) y otra
información relacionada [PRE98].
Métodos. Cada una de las operaciones encapsuladas por un objeto proporciona una
representación de uno de los comportamientos del objeto [PRE98].
Mensajes. Los mensajes son el.medio a través del cual los objetos interactúan. Un
mensaje estimula la ocurrencia de cierto comportamiento en el objeto receptor
[PRE98].
Instancias. Un objeto es una instancia de una clase. Una vez.definida la clase, los
atributos pueden reusarse al crear nuevas instancias de la clase. Todas las operaciones
válidas de la clase están conectadas a la definición del objeto y son heredadas por todas
las instancias de esta clase.
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 definición actual.
Las estructuras de programas orientados a objetos se organizan en clases
taxonómicas. A mayor nivel en la jerarquía corresponde una mayor generalidad, a menor
19
Capítulo 3
MARCO TEÓRICO
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 reusadas 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.
3.4 Lenguajes de patrones
Patrones para el desarrollo de software es uno de los tópicos más nuevos que
emergen de la comunidad de desarrollo de tecnologías orientadas a objetos. 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 difíciles comunes,
encontrados a través de todo el ciclo de desarrollo de software.’Los patrones ayudan a crear
un lenguaje compartido para comunicar conocimientos y eiperiencias acerca de estos
problemas, así como de sus soluciones. Codificando formalmente estas soluciones y sus
relaciones, deja capturar exitosamente el cuerpo de conocimiento que comprende nuestro
entendimiento de buenas arquitecturas que conforman las necesidades de los usuarios.
Cada patrón es una regla de tres partes, el cual expresa una 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. Los autores de “Patterns of Software Architecture” definen tres
tipos de patrones:
1. Patrones de arquitecturu’. Un patrón arquitectónico expresa una estructura de
organización o esquema fundamental para sistemas de software. Provee un conjunto de
subsistemas predefinidos, especifica sus responsabilidades, e incluyen reglas y guías
para organizar las relaciones entre ellos.
2. Patrones de diseio. Un patrón de diseño provee un esquema para refinar los
subsistemas o componentes de un sistema de software, o las relaciones entre ellos.
Comúnmente describe estructuras recurrentes de componentes en colaboración que
resuelven un problema de diseño en general dentro de un contexto en particular.
3 . Patrones de código. Un patrón de código es un patrón d l bajo nivel, específico a un
lenguaje de programación. Un patrón de código descri6e como implantar 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
20
’
Capítulo 3
MARCO TEÓRICO
sistema total, pero definen micro arquitecturas de subsistemas y componentes. Los patrones
de código son técnicas de programación en lenguajes específicos que se ajustan en un nivel
bajo interno o detalles externos de la estructura 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 recurrente a un problema 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. La utilidad del estudio de patrones
radica en que los lenguajes de patrones describen marcos ,de trabajo (fiiarnework) o
familias de sistemas relacionados.
3.4.1 Patrones de diseño
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. Cada patrón de diseño se enfoca
a un tópico o problema de diseño orientado a objetos en particular. 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. Puesto que eventualmente debemos implantar
nuestro diseño, un patrón de diseño también provee el código de ejemplo para ilustrar una
implantación. Aunque los patrones de diseño describen diseños orientados a objetos, ellos
están basados en soluciones prácticas que han sido implantadas en un torrente de lenguajes
de programación orientados a objetos. La forma ‘Alexandriana’,‘GoF’ o forma ‘canbnica’
describe un patrón de diseño:
1. Nombre, es una palabra o frase corta para referirse al patrón, el conocimiento y la
estructura que describe;
2. Problema, describe su intención (INTENT), las metas y objetivos que quiere
alcanzar dentro del contexto y sistema de fuerzas dado, donde con frecuencia, las
fuerzas se oponen a los objetivos;
3. Contexto, describe las PRECONDICIONES bajo las cuales el problema y su
solución parecen recurrir y para lo que es deseable la solución, puede pensarse
como la configuración inicial del sistema antes de que sea aplicable el patrón.
También nos indica la APLICABILIDAD del patrón;
4. Fuerzas, describen las restricciones relevantes y como interactúan aún en conflicto
con cada una de las otras y con las metas que se desean, aquí un escenario concreto
sirve como la MOTIVACIÓN para que el patrón sea utilizado;
5. Solución, representa a las reglas de relación tanto estáticas como dinámicas, que
describen como obtener el resultado deseado. La descripción puede utilizar figuras y
diagramas para identificar la ESTRUCTURA del patrón, sus PARTICIPANTES y
sus COLABORACIONES para mostrar como se resuelve el problema. La
ESTRUCTURA ESTÁTICA indica la forma y la organización del patrón, pero con
frecuencia es el COMPORTAMIENTO DINÁMICO Ib’que hace que el patrón viva;
~
sep-~
,GE.
~ ~ t i DGIT
w P
“--.-a--
-.
1
w,
.
Capítulo 3
MARCO TEÓFUCO
6 . Ejemplos, describen las POSTCONDICIONES y los efectos laterales, buenos y
malos, del patrón. Esto a veces es llamado RESOLUCIÓN DE FUERZAS porque
describe cuales fuerzas han sido resueltas;
7. Razonamiento, explica cómo las fuerzas y las restricciones son orquestadas para
lograr una armonía resonante. Nos dice como trabaja el patrón actualmente y porque
es bueno. A diferencia de la solución, el razonamiento proporciona el conocimiento
de la naturaleza interna de la estructura y los mecanismos clave que están bajo la
superficie del sistema;
8. Patrones relacionados, muestran las relaciones estáticas y dinámicas entre un
patrón y otros dentro del mismo sistema o lenguaje de patrón. Los patrones
relacionados de alguna manera comparten las fuerzas. Los patrones predecesores
tienen un contexto inicial y uno resultante, que es compatible con el contexto
resultante o inicial de otro patrón. El patrón sucesor sigue del patrón con un
contexto inicial. El patrón alternativo, describe una solución diferente al mismo
problema pero bajo diferentes fuerzas y restricciones. Los patrones co-dependientes,
pueden o deben ser aplicados al mismo tiempo que otro patrón.
El catálogo de Gamma et.al.[GAM95]clasifica 23 patrones de diseño de acuerdo a dos
criterios, ilustrados en la tabla 3.1:
Propósito se refiere a lo que hace el patrón,
a) Creacionales: relacionados con el proceso de creación de objetos.
b) Estructurales: trata de la composición de clases u objetos.
c) De comportamiento: caracterizan la manera en la cual clases y objetos interactúan y
distribuyen responsabilidades.
Alcance específica si los patrones se aplican principalmente para clases o para objetos,
a) Clases: relaciones entre clases y sus subclases establecidas a través de la herencia,
fijadas estáticamente en tiempo de compilación.
b) Objetos: relaciones entre objetos que pueden ser cambiadas en tiempo de ejecución.
Comportamiento
Interpreter
Template method
Chain of responsability
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor
22
MARCO TEÓRICO
Capítulo 3
3.5 Gramáticas
Para definir un lenguaje formal L, necesitamos dos cosas:
1) un alfabeto C de símbolos individuales y,
.:
.
2) un conjunto de reglas. para determinar cuales cadenas de'I símbolos del alfabeto son
palabras legales del lenguaje.
Usando esta definición un lenguaje no es otra cosa másique un conjunto de cadenas
legales de un .alfabeto. Tomados juntos el alfabeto y las regias para formar cadenas son
llamados una gramática.
4
Una gramática es un sistema formal para definir un lenguaje, así como también una
herramienta para imponer a las cadenas del lenguaje una estdctura Útil. Es el conjunto de
reglas por las cuales son construidas expresiones válidas d& algún lenguaje. Todos los
lenguajes de programación tienen reglas que describen la estruCtura sintáctica de programas
bien formados [HOP93].
Formalmente una gramática se define por (V, T, P, S), donde:
;!
V: Es un conjunto finito de símbolos no terminales.
T: Es un conjunto de símbolos terminales.
P: Es un conjunto finito de producciones, las cuales tienen la forma A j a , donde A es un
símbolo y oc es una cadena de símbolos de (VuT)*.
S: Es una variable la cual contiene el símbolo de inicio.
3.5.1 Gramáticas libres de contexto
Una gramática libre de contexto es un conjunto de vakiables (también llamado no
terminales o categorías sintácticas), cada una de las cuales representa un lenguaje. Los
lenguajes representados por las variables son descritos recursivkmente en términos de otras
variables y símbolos primitivos llamados terminales. Las teglas que relacionan a las
variables se conocen como producciones[HOP93].Se llaman iramáticas libres de contexto
porque una derivación de un no terminal se puede aplicar indebendientemente del contexto
donde este ubicado ese no terminal.
Las palabras de un lenguaje libre de contexto pueden ser reconocidas por un
autómata push-down (PDA), un PDA esta compuesto d& dos cintas (posiblemente
infinitamente largas). La primera es una cinta de entrada cónteniendo la palabra a ser
reconocida. La segunda es una pila, inicialmente conteniendo '!elsímbolo de comienzo S y
un símbolo de terminación'#.
Las gramáticas libres de contexto tienen muchos usos prácticos, muchos de las
sintaxis de los lenguajes de programación pueden ser especific'ados usándolas, cada uno de
estos lenguajes tienen, sin embargo, construcciones que no son de libre contexto, tal como
el encabezado para un procedimiento con parámetros, parámekos solo tienen sentido en el
contexto de un procedimiento [APP91].
23
Capítulo 3
MARCO TEÓRICO
Una gramática libre de contexto tiene cuatro componentes[AH090]:
1. Un conjunto de símbolos terminales. 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 simbolo 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.
Naturalmente, las expresiones aritméticas pueden ser definidas recursivamente. Los
siguientes ejemplos ilustran como trabaja la definición. Consideremos expresiones que
envuelven:
a) Los cuatro operadores binarios,
b) Paréntesis para agrupar,
c) Operandos que son números y,
.d) Números que pueden ser cadenas de uno Ó más dígitos.
I'
Las producciones son:
<expr> + <numero>
<expr> + (<expr>)
<expr> + -<expr>
<expr> + <expr> <op> <expr>
cop> + + I - I * I /
<numero>+ <numero><digito>
<numero>+ <digitoz
<digito>+O I 1 12 13 14 15 16 17 18 19
Los símbolos terminales son: 0,1,2,3,4,5,6,7,8,9, + - * / ( )
Los símbolos no terminales son: expr,'op, numero y digito.
El símbolo inicial es: expr.
3.5.2 Gramáticas regulares[APP91]
Definiremos una gramática regular en dos pasos. El primero para .definir una
expresión regular e sobre un alfabeto C.
.24
I/
MARCO TEÓRICO
Capítulo 3
1. A (cadena nula) es una expresión regular.
2. Si XEZ,entonces x es una expresión regular.
3. Si e, es una expresión regular, entonces también lo es (e,).
4. Si el y e2 son expresiones regulares, entonces también lo son el
+ el, el ' e2, y el*.
La regla 2 nos dice que cada símbolo del alfabeto es una expresión regular. Nota que
expresiones regulares son encerradas bajo tres operaciones, +(unión), (concatenación) y *
(Cerradura de Kleene). El paréntesis de la regla 3 no es un símbolo del alfabeto, pero puede
ser usado libremente para hacer expresiones claras. Símbolos tal como "(" y 'y'' que
pueden ser usados en expresiones pero que no forman parte del lenguaje mismo,, son
llamados metasímbolos. Para entender la regla 4 consideremos.un ejemplo. Suponer que C
= {x, y), la regla establece que x+y es regular. Aquí x+y significa x ó y , ó el conjunto unión
x y y, si x y y son conjuntos. x y es también expresión regular, como son x , xx, m,...yx,yy,
yyy, my, etc. Podemos escribir q y como (x)(yy) para indicar la concatenación den y yy.
Con expresiones regulares definidas, podremos listar las reglas de una gramática
regular usada para desarrollar un lenguaje regular L, desde una expresión regular e.
Escribiremos L(e) para indicar el lenguaje L definido por e.
1. Si e = x, entonces L(x) = {x}, esto es, la palabra sola en el lenguaje L es x.
L(A) = { A } .
2. Si L(e1) = Li y L(e2) = L2 entonces,
a. L(eie2) = LiLi
b. L(ei+ez) = LI + LZ
c. L(el*) = LI*
Por ejemplo suponer LI = {x} y L2 = {y}, donde'& = x y ez = y. Esto es, cada
lenguaje tiene exactamente una palabra en él, entonces:
a) L(xy) = {xy}, una palabra sencilla, xy
b) L(x+Y) ? {XI+ {Y) = {x, YI
C) L(X*) L* = {A, XX, XXX, ...}
d) L(x* y) = L(x*) L(y) = {y, xy, XXY, X n Y , -1
Los lenguajes regulares son generados por expresiones regulares, cuyas palabras
pueden ser reconocidas por autómatas finitos (deterministas o no deterministas). Un
lenguaje que puede ser reconocido por un autómata finito es equivalente a un lenguaje
regular.
3.6 Generador de parsers [MET-]
Un parser es una herramienta que lee caracteres desde una entrada fuente e intenta
darle sentido a su organización y desempeñar funciones Útiles basadas en esta organización.
En general el parser no lee directamente de los caracteres de entrada, los caracteres de
entrada son leídos por un scanner el cual ensambla los caracteres en tokens. Estos tokens
son entonces leídos como entrada por el parser. El esquema de la combinación parserscanner es mostrado en la figura 3.1.
25
.
. . . .
..
.
MARCO TEÓRICO
Capítulo 3
Caracteres
fuente
Scanner
Caracteres
Tokens
Parser
Un generador de parsers es una herramienta que toma como entrada la
especificación de un parser y un scanner (llamado gramática) y genera como salida el
código que implementa el analizador sintáctico.
Scanners son especificados . en gramáticas usando expresiones regulares
(representan tokens). En el javacc, la sintaxis usada es ilustrada en el siguiente ejemplo:
Token {
<INT: “int”>
<ID: r‘a3,-‘‘zn, “A”-“Z”
3
1
“
-
”] [“ >, >> “A”-“Z”, “0”-“9”,
a - z ,
‘6
‘I
”I)*
-
La especificación anterior contiene dos expresiones regulares, la primera es simple
especifica “int”, mientras que la segunda es comparada por alguna cadena que empieza con
una letra o guión bajo y es seguida por algún número de letras, dígitos o guión bajo.
Los parsers son especificados usando producciones. Una producción define un no
terminal al especificar como puede ser expandido en otros no terminales y tokens. El
siguiente ejemplo muestra como es una producción en javacc:
void varDecl():
{I
{
Type() <ID> [“=” expression()] “;”
I
Esta producción define un no terminal “varDecl” como expansión para el no
terminal “type” seguido por el token “<ID>” seguido opcionalmente por una inicialización
(la cual es el token “=” seguido por el no terminal “expression”) finalizando con el token
“_>>
3.7 JavaCC [MET-]
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:
26
Capítulo 3
' MARCO TEÓFUCO
JavaCC toma como entrada un archivo con extensión jj, el cual debe contener la
especificación de la gramática en formato BNF del lenguaje a analizar y posteriormente
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, figura 3.2, seleccionar el archivo de especificación de
la gramática, dar clic en next.
!
Figura 3.2 Pantalla de generación del analizador
3. Seleccionar las opciones de javacc (figura 3.3), dar clic nuevamente en next.
Figura 3.3 Pantalla de selección de opciones para el analizador
27
-.
..
..
..
MARCO TEÓRICO
Capítulo 3
4. en la última pantalla figura 3.4, dar clic sobre build para generar' el coniunto de
-
programas en Java
que formarán parte del.analizador
,
. _ _ _ _ sintáctico.
-
,
,2
cmnim:
~
I
I
li
F
I
')
I
Cbck on 'Build' to @crate p m m
~
I
.u
!
I
i
!I
.
Id-
.
rmI
"
Q.1
.
.
5. 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 al analizador sintáctico 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 árboles 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 analizadores sintácticos.
28
Capitulo 4
MODELO CONCEPTUAL DEL SISTEMA
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
En este capítulo se describe la solución adoptada para resolver el problema
planteado en el primer capítulo, esta solución se basa en el uso de un analizador sintáctico
construido a partir de la definición de la gramática completa del lenguaje C++; del modelo
canónico de representación de patrones de diseño planteado en el IPADIC++ y de la
herramienta que verifica la estructura de los programas en lenguaje C++ atendiendo a la
sintaxis de este lenguaje.
29
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
4.1 Introducción
En el capítulo uno se describe un problema que tiene relación con la detección de
patrones de diseño en código fuente escrito en el lenguaje C++ que fue implementado en el
IPADIC++ [CAS99], En la detección de patrones que realiza el IPADIC++ no se considera
la gramática completa del lenguaje C+t. Esta limitante conduke a que el analizador del
código que se explora no reconozca todas las secuencias o cadenas de código aunque éstas
sean bien formadas de conformidad con las reglas de la gramática estándar ANSI-IS0 del
lenguaje C++; por lo que en este trabajo de tesis se planteó como una necesidad, solucionar
esta restricción, incluyendo en el analizador'del IPADICtt la gramática estándar de C++.
Por lo tanto se utilizó la arquitectura de entradas y salidas del sistema descrita por el
IPADIC++, con la diferencia de que en el primer módulo .se incluye un analizador
sintáctico que define la gramática completa del lenguaje C++ [VIS96], con este módulo se
extrae información que se guarda en tablas de información, y posteriormente, esta
información se procesa para obtener la forma canónica del código fuente. Esta forma
canónica se pasa al modulo de reconocimiento de patrones de diseño, concluyendo con el
resultado sobre la detección o no detección del patrón de diseño.
A continuación se describe el análisis' realizado p h a el desarrollo de la
investigación, la arquitectura de la herramienta y la interfaz ai usuario.
4.2 Análisis del sistema
Para el desarrollo de la presente tesis fue necesario realizar un análisis del
funcionamiento del IPADICtt, del analizador sintáctico que compila el código fuente
según la gramática del lenguaje C++ y de la información requerida para llegar al objetivo
planteado, a continuación se describe cada uno de estos puntos y las conclusiones a las que
se llegó.
4.2.1 Análisis del IPADIC++
El Sistema para identificación de patrones de diseño en código C++ (IPADIC++)
[CAS991 define un modelo y un lenguaje canónico que sirve para representar la estructura
de los patrones de diseño y transforma por medio de las reglas gramaticales del lenguaje
canónico las relaciones estructurales del código. fuente a su forma canónica. El modelo
consiste en una gramática libre al contexto en notación BNF. Para la forma canónica del
código fuente se utilizan las reglas de producción del lenguaje C++.
La herramienta desarrollada en el IPADICtt esta constituida por dos módulos:
1. Módulopara la transformación de código C++ a la forma canónica: Tiene como
entrada un conjunto de clases en C t t , que pueden estar en uno o 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. Este módulo reconoce en el
código analizado los tipos de relaciones: herencia, agregación, asociación e
instanciación y se genera una cadena (forma canónica del código) que'contiene las
relaciones entre las clases del código. También detecta la cardinalidad de relaciones,
esto es, cuando objetos de una clase se relacionan más de una vez con objetos de
30
.
Capítulo 4
. .
.~
~
MODELO CONCEPTUAL. DEL SISTEMA
otra clase. Además de generar como salida la forma canónica del código analizado,
también proporciona una tabla con las relaciones detectadas en el código en las que
no están involucradas las clases pertenecientes a él, se asume que estas relaciones se
establecen con la librería de funciones o clases del lenguaje C++.
2. Módulo de reconocimiento de patrones de diseño: Este módulo recibe como
entrada el código del programa que se explora, representado en su forma canónica,
y realiza el análisis sobre este código para detectar alguno de los tres patrones de
diseño implementados en el sistema (abstract facto&, composite e iterator).
Asimismo, proporciona como salida un mensaje que especifica el resultado de la
detección del patrón de diseño buscado dentro del código fuente.
La interfaz de la herramienta muestra una ventana (figura 4.1). Esta ventana consta
de un menú que tiene dos opciones: Patrones de diseño y Ayuda.; La opción de Patrones de
diseño permite iniciar el proceso de detección del patrón de diseño seleccionado y la opción
de Ayuda muestra ventanas de dialogo de información acerca del sistema.
Figura 4.1 Pantalla principal del IPADICH
Al seleccionar la opción de Patrones de diseño aparece una ventana de diálogo
(figura 4.2) en la que hay que seleccionar el archivo con extensión CPP a analizar. Una vez
que se selecciona este archivo y se pulsa el botón aceptar, el sistema procede a la detección
del patrón de diseño seleccionado en el código fuente, y concluye con los mensajes de
resultado de la búsqueda del patrón de diseño sobre la forma canónica del código fuente.
Los mensajes de salida son: en el cuadro de texto de relaciones existentes en el código
muestra la forma canónica de las relaciones estructurales entre clases del código fuente; en
el cuadro de texto de relaciones del código que se explora con la librería muestra las
relaciones del código con la librería de C++, y en el cuadro de texto de resultado de buscar
el patrón muestra el resultado de la búsqueda del patrón de diseño en el código fuente. El
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
texto mostrado en resultado de la búsqueda puede ser: “PATRON E N C O N T W O ’ ,
mencionándose las clases que intervienen en el patrón, “PATRON NO ENCONTRADO’,
mencionándose las relaciones que hacen falta para que se tenga el patrón buscado.
Forma canónica del patrón:
-
1
Nombre del archivo a analizar:
D:icrnmiPATRONESiIteratoripruebal .cop
I
Relaciones existentes en el código:
lierator
Relaclanes del código con la librería
Resultado de buscar el patrón:
Figura 4.2 Ventana de diálogo de detección de patrones de diseño
Comentarios:
Es necesario utilizar algunos de los conceptos definidos por el IPAüIC++ como es la
definición del modelo canónico y la definición del autómata de reconocimiento para los
patrones de diseño, así como de la estructura general de entradas y salidas del sistema.
En el módulo de transformación del código fuente a forma canónica, se retoma parte del
procedimiento que une los diferentes archivos de código fuente que están asociados al
archivo principal que se explora, por medio de la directiva de pre-procesamiento
#include. En 1PADICi-i- el orden de obtención de código fuente de cada uno de los
archivos asociados se lleva a cabo conforme se encuentran las llamadas a los archivos
por medio de la directiva #include. Para efectos de implementación en esta tesis, se
pondrán los nombres de los archivos en una pila.
En la obtención de la forma canónica del código fuente, se, requiere de la
implementación de un analizador sintáctico que realice la compilación del código
fuente con respecto a la gramática completa del lenguaje C++ . Esta forma canónica
servirá como entrada del modulo de reconocimiento de patrones de diseño.
AI modulo de reconocimiento de patrones de diseño &‘le añadirán las acciones
correspondientes para la detección de los’ patrones de diseño Strategy y Template
method.
Se debe modificar el funcionamiento de la interfaz con el usuario para optimizar el
tiempo de ejecución del sistema.
32
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
4.2.2 Estudio del analizador sintáctico que compila el código fuente según la
gramática del lenguaje C t t
Analizador sintáctico de la gramática del lenguaje C++ desarrollado en JavaCC por
Sreenivasa Viswanadha [VIS96]. Esta herramienta tiene asociados los siguientes archivos
java que ayudan en la determinación de los alcances de las variables que forman el
programa analizado:
Scope.java es una clase que maneja datos de una clase o función. Como es el nombre, el
tipo (si es clase o tipo), contiene una tabla parcial de símbolos que están dentro de está
clase o función, y el nombre de la clase o función a la que pertenece.
CIassScope.java es una clase que hereda de Scope, esta clase guarda todas las superclases
de las que una clase es derivada.
DecIaration.java es una clase que guarda los atributos de una declaración; el nombre, el
alcance, usa una variable que define si es clase o no y otra variable booleana que define si
es tpedef o no. Esto se llena conforme la declaración es analizada
SymtabManager.java clase que maneja la tabla de símbolos y alcances dentro de una
unidad de traducción dada. Consta de las siguientes variables:
scopeTuble es un objeto de tipo Hashtable, es una tabla de símbolos global indexada
por nombre del alcance (clase o función).
scopeStuck pila de alcances que tiene un máximo anidamiento permitido de 100, es un
arreglo que contiene clases Scope.
depth variable de tipo entero inicializado en cero y nos indica la profundidad de
anidamiento de scope.
Además, contiene los siguientes métodos:
J Openscope: este método abre un nuevo alcance (con nombre y bandera de tipo
opcionales).
J PutTypeName: este método pone el nombre pasado como argumento en la tabla de
símbolos tipo introducidos en la clase o función que esta en la posición depth de la pila
de clases o funciones.
J IsFullyScopedTypeName: este método regresa un valor booleano, si el nombre que
recibe como argumento es un nombre de tipo dentro de los alcances manejados.
J IsTypeName: retorna un valor booleano que nos indica si el nombre se encuentra dentro
de las tablas de símbolos definidos dentro de los, alcances (clase/función) que se
encuentran en la pila de alcances.
J CloseScope: método que cierra el alcance al disminuir en uno la profundidad de
anidamiento en los alcances.
J IsCtor: retorna un valor booleano que indica si el nombre que recibe es el nombre de un
método igual al de una clase.
J GetCurScope: este método retorna el objeto de tipo Scope actual.
J GetScope: retorna el objeto Scope correspondiente al nombre pasado como parámetro
ai método.
J GetScopeOfFullyScopedName: retorna un objeto de tipo Scope correspondiente a B en
A::B::C (pasándole B como parámetro al método) .
J IsGlobalScope: retorna un valor booleano si la profundidad de anidamiento de Scope
.
(clase/función) es uno o dos.
'
33
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
AI compilar el archivo CPLUSPLUS.jj se generan los archivos CPPParser.java,
CPPParserConstants.java, CPPParserTokenManager.java,ParseException.java, Token.java,
TokenMgrError.java.
La ejecución del programa CPPParser comienza abriendo 'el archivo con extensión
CPP a analizar, pone su contenido en una variable de flujo de entrada de archivo, si no hay
error crea una instancia llamada parser, de la clase CPPParser y ejecuta el método
traslation unit() este método inicia abriendo un alcance para el programa a analizar. Define
un programa de C++ como una unidad de traducción y a la unidad de traducción como un
grupo de cero o más declaraciones externas seguidas de un token de fin de archivo
(<EOF>). Las declaraciones externas a su vez se definen como uno de los siguientes tipos:
Declaración
Enumeración
Definición de destructor
Definición de constructor
Definición de función
Declaración o definición de función de conversión
Encabezado de plantilla
Estos tipos se derivan en otras producciones que definen cada una de estas partes en
la gramática del lenguaje C++.
Comentarios:
En este analizador sintáctico solo se realiza un análisis de sintaxis de código fuente
escrito en lenguaje C++. Hace uso de otras clases que ayudan en el reconocimiento de
los alcances de cada una de las clases, variables y funciones que forman el programa
analizado.
El analizador sintáctico no reconoce el salto de línea y las directivas del pre-procesador.
Se incluyó en,el analizador sintáctico el reconocimiento de los saltos.de línea.
Se detectan los puntos en los que serán incluidas las accionesisemánticas para obtener la
información necesaria para poder escribir la cadena de símbolos que contenga la forma
canónica del código fuente.
. Para obtener la información requerida se incluyeron acciones semánticas en
Declaración y definición de función, dentro de las derivaciones de declaración es donde
se extrae la infórmación referente a las clases y las relaciones de herencia, agregación,
asociación e instanciación. Y dentro de las derivaciones de la declaración de función se
extrae la información referente a las funciones como es su nombre, el alcance que tiene
cada función y la localización de estructuras $0 switch anidadas.
4.2.3 Nuevos patrones
Para poder realizar el reconocimiento de los patrones de diseño se requiere de la
siguiente información:
34
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
Factory method
03 Clases Participantes:
Cliente
Creador-abstracto
Creador-concreto [n]
Producto abstracto
Producto~concreto[n]
*:* Relaciones:
Herencia
Instanciación
Asociación
Para el reconocimiento de este patrón, se requiere de encontrar al menos una clase
derivada (Creador-concreto[n]) de otra clase abstracta (Creador-abstracto) y que esta clase
derivada efectué la instanciación de un objeto de clase (Producto concreto[n]) la cual debe
ser derivada de la clase abstracta (Producto-abstracto); o encontrar solo una clase que
instancie objetos de otra clase y hacer la observación de que se pueden incluir las clases
base de cada una de ellas para que se cuente con el patrón.
.
..
9
Strategy
-3 Clases Participantes:
Context
= Strategy (clase abstracta)
Concrete-Strategy [n]
*3 Relaciones:
Herencia
= Agregación
Para el reconocimiento de este patrón hay dos opciones:
1. Si se encuentra la instrucción switch o $(anidados en más dé tres niveles), se puede
sugerir la implementación de este patrón poniendo el código correspondiente a cada
opción del switch en un método Interfaz dentro de una clase Concrete Strategy.
Además de implementar una clase Strategy, de la que se derivaran ias clases
Concrete-Strategy, en esta clase definir un método virtualmente puro Interfaz. Y
finalmente, implemeritar una clase Contexto en la que se manejarán las opciones del
$o switch, agregar a esta clase la clase Strategy.
. . 2 . Por estructura se tendrían que encontrar clases Concrete-Strategy que hereden una
interfaz común para la implementación de un algoritmo y una clase contexto que
mantiene una referencia a un objeto Strategy, se puede d e f i n i k a interfaz que deja
que la clase Strategy acceda a los datos o pasarse la clase contexto como un
argumento para operaciones Strategy.
.
.
9
Template method
*3 Clases Participantes:
Abstractclass
= Concreteclass
4 4 Relaciones:
Herencia
9
9
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
Se debe reconocer en una clase base (abstractclass), un método plantilla dentro del cual
se hagan llamadas a otros métodos (primitivos) virtualmente puros que las subclases
(Concreteclass) reemplazan para proveer comportamientos concretos.
Para poder obtener y manejar la información anterior se requiere del uso de las
siguientes tablas de información, de las que se ejemplifica su contenido en las tablas 4.1:
J
Archivos: El nombre del archivo que contiene la función main corresponderá a la
clase cliente, posteriormente siguiendo la directiva #include, se analizarán los
códigos asociados al código de la clase cliente, para detectar todos los nombres de
archivos asociados.
J Clases: Nombre de clase y relaciones (herencia, agregación, asociación e
instanciación) que existen entre ellas.
J Funciones: Nombre de la función, clase a la que pertenece la función. Nombre de la
función en la que existen i f s con más de 3 anidamientos o switch con más de 3
case. Relaciones entre las funciones (formales y actuales).
Tablas 4.1: Ejemplo del contenido de las tablas de información
36
MODELO CONCEPTUAL DEL SISTEMA
Capítulo 4
F actual
Clase
ConcreteAggregate
ConcreteIterator
Aggregate
F formal
Open
Add
Operation
Iteratoradd
main
First
INST.ELSE
False
False
SALIO
NIVEL
True
4.3 Arquitectura de la herramienta
Ésta herramienta esta constituida por dos módulos: Módulo para la transformación
del código C++ a la forma canónica y Módulo de reconocimiento de patrones de diseño;
implementados en el lenguaje de programación Java y en el generador de parsers javacc.
La arquitectura de la herramienta se ilustra en la figura 4.3. El diagrama de clases de la
herramienta en notación OMT se muestra en las figuras 4.4, 4 . 5 4.6.
~
\I"".6Y
I Pi.l...*Dli"
I
1, I
.
Parse;dela
gramatia del
lenguale C U
I Modelo de
~
I
Representación
canónica de codigo
I
I
Desplegado de a que
patrón corrcsponde o a
cual se parece
1
Tablas de
información
I
I
t
"I
del e6digo a la forma canónica
de patrones de diseña
Figura 4.3 Estructura general de la herramienta
37
MODELO CONCEPTUAL DEL SISTEMA
Capítulo 4
____.
*FCPD()
..-~
Pantalla
w
h : DialogHandler = new DialogHandler ()
+detecta()
Abrir
bandarch : boolean =false
rror: boolean =false
,/
*Abrir()
*nom breSinEkt0
modulo2/
I
d
+ieico(.)
%tros-arch()
%et-codigo()
$getTablas()
$get-rlib()
$mosb-ar-inf-tab()
*inicialira()
*buscaFun()
*getTernplatesO
%eRegRep()
$bus caClas eRel()
*buscaClas eRelLibi
BfonnaCanonica()
*buscaRegFun()
Figura 4.4 Diagrama de clases de la herramienta
38
1
MODELO CONCEPTUAL DEL SISTEMA
Capítulo 4
4.3.1 Módulo para la transformación del código C++ a la forma canónica
En este modulo se convierte el código escrito en lenguaje C++ a su forma canónica
en la figura 4.7 se ilustran las entradas y salidas para este modulo.
.
Paner de la gramática
1
I
4
+I
I
Closol ASOCIACION
dmd, close3
AGREGACION clare2,
V
ASOCIACION clareS
ACRECACION closed
INSTANCIACION cloreZ,
I closoZ HEREDA &re3
código a 18 foma can6nica
Figura 4.7 Entradas y salidas del módulo para transformar el
código escrito en lenguaje C++ a la forma canónica
Este módulo tiene como entrada el archivo de definición de las clases que forman
un programa escrito en lenguaje C++, estas definiciones pueden estar en uno o varios
archivos; en el caso de que estén en varios archivos debe de incluirse en cada uno de los
archivos la directiva #include con el nombre del archivo o archivos en los que se encuentra
la definición de las clases de las que hace uso, es importante el orden en que se encuentren
las definiciones de estos archivos y se obtiene como salida la forma canónica del código
fuente analizado. Las clases principales en este modulo son CPPParser y ManTabData (ver
diagrama de clases, figura 4.5). CPPParser es la clase que realiza el análisis sintáctico de la
gramática del lenguaje C++, esta clase a su vez tiene asociadas otras clases que genera
automáticamente javacc, tiene además clases que ayudan a verificar los ámbitos de alcance
de cada una de las clases y variables que forman los programas analizados. ManTabData es
la clase manejadora de las tablas de información necesaria para obtener la forma canónica
del código analizado.
Los pasos seguidos para la construcción de este módulo son los siguientes:
1. Se inicia obteniendo los nombres de los archivos asociados al programa cliente por
medio de la directiva #include, con esta lista de nombres se une el contenido de estos
archivos en un solo código fuente. Este archivo es pasado como entrada al analizador
sintáctico que verifica la estructura sintáctica del código fuente de acuerdo a la
gramática completa del lenguaje C++.
2. Una parte de este módulo se generó utilizando la herramienta JavaCC haciendo us<>del
archivo CPLUSPLUS.jj en el que se especifica la gramática del lenguaje C++, este
40
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
archivo tiene asociados archivos de java que le ayudan en la implementación del
proceso de análisis semántico para la resolución de ambigüedades.
3. Se estudió el analizador sintáctico que verifica la gramática y se detectaron los puntos
en los que se definen cada uno de los datos que se requieren para llenar las tablas de
información, con las que se podrá obtener la cadena que contenga la forma canónica del
código fuente. Se implementó una clase de java llamada ManTabData, esta clase
contiene los métodos que manejan las estructuras de cada una de las tablas de
información así como las tablas mismas, esta clase es asociada al analizador sintáctico y
utilizada durante el proceso de reconocimiento del código fuente guardando la
información requerida en las tablas de esta clase.
4. Después de lo anterior, se invocó a la herramienta JavaCC, para generar las clases
pertenecientes al analizador.
5 . Posteriormente se invocó al compilador de Java para generar el código de bytes
(Bytecode) del analizador. Después de ésto, el analizador está listo para llamarse desde
cualquier otra clase.
6 . Una vez que concluye el proceso de reconocimiento del código fuente, se procesa la
información contenida en las tablas para obtener la forma canónica del código fuente.
7. Esta forma canónica es devuelta como salida de este módulo.
Para la realización del punto tres fue necesario identificar en el código fuente los
puntos clave en el código donde se escriben las acciones semánticas para la obtención de la
información necesaria para llenar las tablas, estos puntos son descritos a continuación:
Para las clases, en el código fuente en la definición de una clase el nombre de la clase
corresponde al identificador que se encuentra después de la palabra reservada “class ”. El
archivo que contiene la función main, se toma como clase (cliente), por lo tanto se toma el
nombre del archivo como el nombre de la clase.
Para la herencia, en el código fuente en la definición de una clase se especifican dos
puntos(:) seguidos del nombre de otra clase, el nombre de la clase hija corresponde a la
clase definida y el nombre de la clase padre corresponde al identificador que se encuentra
después de los dos puntos(:).
Para la agregacibn, en el código fuente se identifica en la declaración de variables
miembro de la clase, donde el tipo de la variable declarada corresponde al nombre de la
clase agregada a la clase que se esta definiendo. En caso de que se encuentre más de una
declaración de este tipo se especifica la agregación con cardinalidad, colocando el postfijo
[n] al final del nombre de la clase agregada. Así el nombre de la clase compuesta es la clase
que se esta definiendo y el nombre de la clase agregada es el nombre de la clase que
corresponde al tipo de la variable que se esta definiendo.
41
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
Para la asociación, en el código fuente se identifica en la declaración de variables
miembro de la clase, donde el tipo de la variable declarada corresponde al nombre de la
clase asociada a la clase que se esta definiendo este tipo se encuentra declarado como un
apuntador, es decir va seguido de un asterisco. En este tipo de relación se especifica la
cardinalidad [n] en la clase conocida para todos casos de asociación que se den en el código
fuente ya que un apuntador a un objeto de clase especifica el inicio de una lista de objetos
de la clase que se esta asociando. Así el nombre de la clase conocedora es el nombre de la
clase que se esta definiendo y el nombre de la clase conocida es el nombre de la clase a la
que se apunta.
Para la insfunciación, en el código fuente se identifica en las instrucciones que
forman el código de una función, la devolución de un nuevo objeto del tipo de la clase
instanciada. Así el nombre de la clase creadora es la clase en la que se encuentra la función
y el nombre de la clase creada es el nombre de la clase instanciada.
Para las funciones, se encuentra en el código un especificador de tipo que es
devuelto por la función, seguido del nombre de la función ligado opcionalmente a un
alcance con alguna clase(::) donde se especifica antes de los cuatro puntos el nombre de la
clase a la que pertenece la función y después de los cuatro puntos el nombre de la función
seguido por paréntesis que abre y una lista opcional de parámetros seguido de un paréntesis
que cierra. Dentro de cada función puede haber un llamado a otras funciones.
A continuación se ejemplifica en código cada uno de los puntos descritos en los
párrafos anteriores:
//Archivo pruebal.cpp
#include "c:\\patrone
#include "c:\\patrones\\PD-composite\\composite.cpp"
int main (void){
Leaf 11 = new Leaf(-l);
Leaf 12 = new Leaf (-2);
composite ci = new Composite(1);
Composite c2 = new Cornpocite(2);
ci.add(&li) ;
c2.rernoveComposite(&cl) ;
return ( 0 ) ;
I
//Archivo: Component.hpp
#include <iostream.h>
class Component{
e clase: Component
\
42
Capítulo 4
private :
MODELO CONCEPTUAL DEL SISTEMA
Clase que conoce: Component
Clase conocida: Component[n]
//Archivo:Composite.cpp
#include "c:\\patrones\\PD composite\\component.hpp"
e a s s Composit
c Component, { . IClase hija: Composite
Clase padre: Component
public:
Composite(int id){ first = NULL; -identification
virtual void add (Component*);
virtual void removeLeaf(Component*) ;
virtual void removeComposite(Component*);
virtual void operation (void);
void operation(Component*);
=
id;}
Clase que conoce: Composite
Clase conocida: Component[n]
//Archivo: Leaf.hpp
#include "c:\\patrones\\PD composite\\component.hpp"
class Leaf : public Compon&t{
Leaf
L
I
Clase padre: Component
I
public:
Leaf(int id) { - identification
.
= id;)
virtual void operation(void)
{coutcc"Leaf: " < c-identification<<endl;}
private :
int -'identification;
1;
class ConcreteFactoryl: public AbstractFactory {
private :
int Identificacion;.
43
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
public:
ConcreteFactoryl(int ID) { Identificacion = ID; } ;
virtual AProductoA *CreateProductA(int);
virtual void Prtívoid) (
cout c c 'IConcreteFactoryl: I' c c Identificacion < e endl;
1
} ; / / Fin clase AbstractFactory.
AProductoA *ConcreteFactoryl::CreateProductA(int I) {
return(new CProductoAOíI) ) ;
T
1'
1
Clase Creadora: ComcreteFactoryl
Clase Creada : CproductoAO
Clase propietaria: Composite
Loid Composite::operatiofj(Component* c) {
Y
static int level = O;
Component *t;
c->operationO ;
if(c->compositeDetect){
for(t=( (Composite *)c)- > -first; t; t=t->getchild()){
operation(t1 ;
1
level--;
Función actual: operation
Función formal: operation
1
-Las restricciones de este módulo son las siguientes:
Se analiza únicamente código escrito en lenguaje C++.
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.
Debido a que en C++ es difícil 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
al objeto o como un apuntador (referencia) al objeto, en cambio Asociación se
implementa declarando un apuntador al objeto (para más información ver el apéndice
A); cuando se encuentra una relación implementándose a través de un apuntador se
considera como Asociación, si se encuentra sin apuntador es considerada como
Agregación.
Durante el reconocimiento de la estructura sintáctica del código fuente se reconoce
y guarda información acerca de las clases y los diferentes tipos de relaciones que se pueden
encontrar en los patrones de diseño: Herencia, Agregación, Asociación e Instanciación,
44
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
posteriormente esta información se procesa para obtener la forma canónica. En la figura 4.8
se muestra un ejemplo en el que se visualiza el resultado de ejecutar el módulo en cuestión.
'ARCHIVO c:\patronesWD~camposile\component.hpp"
'include <iastream.h>
lass Component(
iublic:
Component()(-nexf = NULL;)
virtual void operation(void) = O;
Component* getchild(vaid) const {ream next;)
virtual void setchild(Companent* next) {_next = next;)
v i m a l int campasiteDetecl() (rehirn(O);}
invate:
Component' n e x t ;
IARCHIVO c:\patronesiPD-~omposit~\~ompasite.hpp"
[include c:\\patrones\WD_camposite\\camp~~~~t.hpp"
lass Composite: public Component{
iublie:
hmposile(in1 id){-first = NULL; -identification = id;)
vimal void add(Component*);
viI1uoI void removeLeaf(Componen1');
virtual void removeComposite(Component');
virtud void operatian(vaid);
void opfration(Camponen1');
v i m a l in1 eompositeDetect() (return(i);)
.¡yate:
int -identification;
Component' -first;
IARCHIVO c:\patronesWD-~omposite\lcaf.hpp"
tinelude "c:\\patranes\WD~composite\\cornponenl.hpp"
,lass Leaf: public Component(
Bublic:
Leaf(in1 id){-identificatian = id;)
vinual "aid aperatian(vaid)
(caut«"Leaf: "«identi fication«endl;)
invale:
in1 _identification;
/ARCHIVO C\ppatranesWD-Composit~\p~~b~l
.cpp
linclude "c:\\patranes\\PD~compos~t~\\composite.cpp"
linclude "c:\\ppalrones\iPD_comp~~it~\\l~~f.hpp"
nt main(vaid)(
Leaf II =new Leaf(-l);
Leaf I2 =new Leaf(-2);
LeafLl =newLeaf(l);
Leaf L2 =new Leaf(2);
Composite C I =new Composite(1);
Composite c2 =new Compasite(2);
Camposite c3 =new Compasite(3);
c l .add(&ll);
cl .add(&12);
c3.add(&L1);
e3.add(&L2);
cZ.add(&cl);
c3.add(&c2);
c3.operation(&c3);
c3.opcration(&c3);
conversión
del código L
canónica
Component,
prueba1
A GREGACION
LeafPI
AGREGACION
Composite[n],
Leaf HEREDA
Component,
Composite
HEREDA
Component
ACQUAINTANCE
Component[n],
Component
ACQUAINTANCE
Component[n]
Figura 4.8 Ejemplo en el que se
visualizan entradas y salidas del
módulo.
c2.removeComposite(&cl);
c3.operation(&c3);
..........I "%.
45
MODELO CONCEPTUAL DEL SISTEMA
Capítulo 4
Este módulo también detecta la cardinalidad de relaciones, es decir, cuando una
clase se relaciona más de una vez con 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.
4.3.2 Módulo de reconocimiento de patrones de diseño
En este módulo se implementa el reconocimiento de los patrones de diseño, toma
como entrada la forma canónica del código fuente y el patrón de diseño a ser localizado, y a
partir de un análisis de éste código detecta si se encontró el patrón de diseño buscado. Las
entradas y salidas de este módulo se visualizan en la figura 4.9.
Desplegado de a que
patrón corresponde o
I
AbstractFactary
recOnOclmientO
Figura 4.9 Entradas y salidas del módulo de reconocimiento de
patrones de diseño
En esta tesis se agrego al modelo, la implementación para el reconocimiento de los
patrones de diseño Strategy y Template method, el patrón de diseño factory method por
razones de tiempo no fue implementado en el sistema.
Los pasos seguidos para la construcción de este módulo son los siguientes:
1. Se comprobó que la forma canónica generada por el primer módulo funcionara
correctamente como entrada para este módulo.
2. El reconocimiento de los patrones de diseño strategy y tempiate method, se hizo
basándose en el comportamiento del programa analizado. Para el strategy se tomó en
cuenta las estructuras if0 switch anidadas presentes en el código. Para el patrón template
method se tomó en cuenta los métodos o funciones que hacen llamado a otras funciones
46
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
de la misma clase. La forma canónica de.los patrones fue realizada apoyándose en el
modelo canónico para la representación de patrones de diseño[CAS99], y en la
estructura de cada patrón (ver anexo B).
3. En este módulo la clase Detección hace uso del programa empate2.jj en el que se
especifica la gramática d e , los patrones de diseño abstract factory, composite e
iterator[CAS99].
4. Para los patrones de diseño template method y strategy se hace uso de la información
obtenida del código durante el análisis del mismo, guardada en las estructuras que
maneja la clase MantabData de donde se obtiene la información relacionada con estos
patrones.
5 . Para el template method, en el análisis del código fuente con la clase CPPParser, se
identifica en las sentencias que son declaraciones si se trata de la llamada a una función
de ¡a misma clase (función formal), en este punto ya se tiene el nombre de la función
que llama (función actual), el nombre de la clase a la que pertenece la función actual, el
nombre de la función actual y el nombre de la función formal se guardan en una tabla
de información manejada por la clase ManTabData.
6 . Para el strategy, en el análisis del código fuente con la clase CPPParser, se identifican
las sentencias $ o switch anidadas, se manejan para este fin tablas de información
auxiliares en las que se guardan contadores y variables booleanas con las que se
controla el conteo de niveles de anidamiento de sentencias $ o switch existentes en el
código, por último se guardan en una tabla de información manejada por la clase
ManTabData cada $o switch que tenga tres o más niveles de anidamiento.
7. Después de lo anterior, se invocó a la herramienta JavaCC, para generar las clases
pertenecientes al analizador.
8. 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 clase cliente.
En la figura 4.10 se muestra un ejemplo en el que se visualizan la entrada al módulo
tratado aquí, y la salida arrojada por el mismo.
47
Capítulo 4
AProductoB, AProductoA,
AbstractFactory, prueba1
AGREGACION ConcreteFactoryl
AGREGACION ConcreteFactoryZ
AGREGACION AProductoA
AGREGACION AProductoB,
ConcreteFactoryl HEREDA
AbstractFactory CREATES
CProductoAO CREATES
CProductoBO, ConcreteFactoryZ
HEREDA AbslractFactory
CREATES CProductoAl
CREATES CProductoBl,
CProductoAO HEREDA
AProductoA, CProductoBO
HEREDA AProductoB,
CProductoAl HEREDA
AProductoA, CProductoB 1
HEREDA AProductoB
MODELO CONCEPTUAL DEL SISTEMA
client
ACQUAINTANCE
apa
ACQUAINTANCE
af, af, cfl
HEREDA af
CREATES pa,
apa, pal HEREDA
reconocimiento
de patrones de
PATRON ENCONTRADO:
CLASES ABSTRACTAS:
AProductoB
AProductoA
AbstractFactory
PRODUCTOS:
CProductoA0
CProductoBO
CProductoAl
CProductoBl
FABRICAS:
ConcreteFactoq
ConcreteFactory2
CLIENTES:
prueba1
Figura 4.10 Ejemplo en el que se visualizan entradas y salidas del módulo de
reconocimiento de uatrones de diseño.
4.4 INTERFAZ AL USUARIO
En el sistema se implement6 una nueva interfaz como se muestra en la figura 4.11,
la cual consta de un menú desplegable y tres paneles de datos. En el área de texto del
primer panel se muestra el código fuente correspondiente al programa escrito en lenguaje
‘i
C++ a analizar. En la segunda área de texto del siguiente panel se muestra la forma
:.
canónica del código fuente y la forma canónica del patrón de diseño elegido para detectar
en el código fuente. En el tercer panel se tienen cuatro áreas de texto en la primer área de
texto se muestran las relaciones del código fuente con librerías de C++, en la segunda se
muestra el resultado de la detección de contadores i f s anidados con más de tres niveles o
switch con más de tres casos, esto es con el fin de indicar la clase y la función en la que se
encuentran para que el usuario pueda optar por usar en estos puntos el patrón strategy, en la
tercer área de texto se muestra el resultado de la búsqueda de métodos plantilla en las clases
y en la Última área de texto se muestra el resultado de la detección del patrón de diseño. En
el anexo C se describe el funcionamiento del sistema.
48
Capítulo 4
MODELO CONCEPTUAL DEL SISTEMA
ódigofuente
Forma canónica de código fuente
Relaciones del cód. con lib.
1
1UI
'
8
'I
.
,
I ¡
:
;;I
I
./I
.
/
- '
,
Estructuras Strategy
!
.
Métodos Piantilia en clases
I
.j
Resultado de la detección
I
!
I
!
:
Forma canónica del patrán de diseño
I
.o -"
p-L_
. . .. ..
'~
~
~
."
-.-
. .
Fi-fl.
_-_
-.
- . .- ~
''
.,. -.
--
.-..
~
..
-t==--
. , . -
wJXZIFuMir--iin
Figura 4. I1 Interfaz principal del sistema
49
.-.
Capítulo 5
.
. -
.
~
..
EVALUACI~NEXPERIMENTAL
Capítulo 5
EVALUACI~N
EXPERIMENTAL
-.
En este capítulo se detallan las pruebas experimentales realizadas sobre la
herramienta generada en este proyecto de tesis. Se enuncia la hipótesis de investigación, se
definen los casos de estudio a utilizar en estas pruebas, los instrumentos de medición
aplicados, el plan de pruebas, los resultados de las pruebas, y el resumen de resultados.
50
EVALUACI~NEXPERIMENTAL
Capítulo 5
5.1 Hipótesis de investigación
La hipótesis de investigación planteada en la propuesta de este proyecto de tesis fue:
Es posible la identificación automática de patrones de diseño en código fuente, de la
sintaxis completa del lenguaje C++, a través de la implementación de un modelo de
representación canónica tanto de los patrones de diseño como del código fuente a analizar.
Durante el desarrollo de esta investigación se obtiene un resultado positivo que es
confirmado con la evaluación experimental.
5.2 Definición de casos de estudio
IPADIC++, solo considera puntos específicos de la gramática del lenguaje C t t para
obtener la información que necesita en el reconocimiento de los patrones de diseño abstract
factmy, composite e iterator, por lo que tiene algunas limitaciones, como es, el
reconocimiento de relaciones en las que al mismo tiempo que se declara el objeto se hacen
otras operaciones con él. En el desarrollo de la presente tesis uno de los objetivos es la
implementación del reconocimiento de la gramática completa del lenguaje C++ en la
generación de la forma canónica de códigos fuente analizados para detectar en estos
patrones de diseño.
Debido a lo mencionado en el párrafo anterior el criterio principal de prueba, es que
se deben de obtener formas canónicas semejantes a las obtenidas en los casos de estudio
utilizados por el IPADICtt; en segundo lugar, al pasar esta forma canónica al módulo de
reconocimiento de patrones de diseño debe obtenerse el mismo resultado que el obtenido
por el IPADICtt; por otra parte, se prueba el reconocimiento de los patrones de diseño
strategy y template method.
5.3 Instrumentos de medición aplicados
Con objeto de comprobar lo enunciado por la hipótesis planteada en el presente
trabajo de investigación, se deben detectar los patrones de diseño incluidos en esta
investigación haciendo uso del modelo canónico de representación de patrones de diseño.
En la detección del patrón puede concluirse con dos resultados, uno es el reconocimiento
del patrón de diseño correspondiente y el otro es que no se detecten patrones. El
instrumento de medición aplicado es propiamente la herramienta desarrollada en esta tesis,
lo que sirve para demostrar que es posible realizar la identificación automática de patrones
de diseño en código fuente, de la sintaxis completa del lenguaje C++, a través de la
implementación de un modelo de representación canónica tanto de los patrones de diseño
como del código fuente a analizar.
.
5.4 Plan de pruebas
El plan de pruebas incluye dos puntos principales:
Plan 01. Se realizan doce casos de prueba que consisten en evaluar el sistema mediante la
comprobación de la forma canónica obtenida por el IPADIC++, haciendo el
reconocimiento de los código evaluados considerando la gramática completa del
51
Capítulo 5
EVALUACI~NEXPERIMENTAL
lenguaje C++, debiendo obtener en este punto una forma canónica basada en el
modelo canónico definido en el I P A ü I C t t [CAS991 y, al realizar el reconocimiento
de los patrones de diseño obtener el mismo resultado.
Plan 02. Se realizan ocho casos de prueba en los que se verifica la forma canónica basada
en el modelo canónico [CAS99], y al realizar el reconocimiento de los patrones de
diseño strategy y template method, se pueden obtener dos resultados que son
PATRON ENCONTRADO o PATRON NO ENCONTRADO.
5.4.1 Requisitos ambientales
Las características y propiedades físicas y lógicas requeridas para el ambiente de
pruebas son las siguientes:
*3 Equipo:
9 Computadora personal con la siguiente configuración:
J Procesador Intel PI11 o superior.
J 128 MB de memoria RAM o más.
J Espacio de 2 GB en disco duro o más.
J Monitor de alta resolución o superior.
J Tarjeta gráfica de 1024x768 píxeles y color de alta densidad de 16 bits o
superior.
J Mouse.
Teclado.
40 Sistema Operativo:
9 Windows 98 o superior.
*:
Herramientas:
9 Java Compiler Compiler, JAVACC 2.0.
9 Lenguaje de programación Java, JDK 1.2.1 o superior.
9 Medio ambiente de trabajo para programas java, Kawa.
*:*
Programas de prueba:
> Archivo con el código fuente de los programas completos especificados en los
casos de prueba que se van a analizar.
*:*
Programación:
9 Clases que muestran la ventana principal, ejecutan acciones del menú principal.
J Programa principal PrincipaLjava.
J Archivo Pantalla.java.
J MyMenu.java
J MyMenuBar.java
J Archivo Abrir.java.
J Archivo Deteccion.java.
J Archivo F-C-P-D.java.
52
Capítulo 5
>
EVALUACIÓN EXPERIMENTAL
Especificación de la gramática del lenguaje C++, expresada en lenguaje JavaCC,
CPLUPLUS.ii.
J Programa-principal CPPParser.java.
J Archivo CPPParserConstants.java.
J Archivo CPPParserTokenManager.java.
4 Archivo ParseException.java.
J Archivo Token.java.
J Archivo TokenMgrError.java.
J Archivo ClassScope.java.
J Archivo Declaration.java.
J Archivo Scope.java.
J Archivo SymtabManager.java.
J Archivo ManTabDat.java.
k Especificación de la gramática para el reconocimiento de los patrones de diseño,
expresada en lenguaje JavaCC, empate2.Jj.
J Programa principal empate2,java.
J Archivo EmpateZToken Manager.java.
J Archivo TokenMgrError.java.
4 Archivo ParseException.java.
J Archivo Token.java.
4 Archivo ASCII Charstream.java.
J Archivo Empat&Constants.java.
5.4.2 Características a ser probadas
Plan O1
Reconocimiento del patrón de diseño “abstractfacfovy”.
Reconocimiento del patrón de diseño “composite”.
Reconocimiento del patrón de diseño “iterator”.
Reconocimiento de un patrón de diseño incorporado dentro de la estructura de
otro patrón de diseño.
Plan 02
Reconocimiento del patrón de diseño “sfrufegv”.
Reconocimiento del patrón de diseño “template mefhod’.
Reconocimiento de un patrón de diseño incorporado dentro de la estructura de
otro patrón de diseño.
5.4.3 Características a no ser probadas
Plan O1 y Plan 02
No se hará la prueba del reconocimiento estructural de otros patrones de diseño
que no sean los que reconoce el sistema.
No se realizará el reconocimiento de las directivas de pre-procesamiento excepto
la directiva #include, en la compilación del código fuente.
53
EVALUACI~NEXPERIMENTAL
Capítulo 5
5.4.4 Especificación de entrada
Plan O1 y Plan 02
Interactivamente seleccionar el nombre del archivo que contiene la clase cliente del
código a analizar y seleccionar el patrón de diseño a detectar.
5.4.5 Especificación de salida
Plan O1 y Plan 02
El sistema desplegará cualquiera de los dos siguientes resultados de la búsqueda del
patrón de diseño en la forma canónica del código fuente:
1. “PATRON ENCONTRADO”, desplegar los nombres de las clases que
intervienen en el patrón de diseño.
2. “PATRON NO E N C O N T W O ’ , indicar las pautas a seguir para darle la
forma o la estructura del patrón de diseño elegido para detectar en el código
fuente analizado.
5.4.6 Identificación de pruebas
Las pruebas se realizaron sobre tres conjuntos de programas de aplicación
codificados en lenguaje C++:
El primer conjunto de programas al que denominaremos “A” (ver anexo B), consta
de programas bajados de internet utilizados para realizar el plan de pruebas del IPADICH
[CAS99], en los que de antemano se sabe que fueron implementados bajo un patrón de
diseño.
Caso
1
2
3
Característica de Prueba
Reconocimiento de patrones de diseño “abstract factory”, sobre el conjunto de
programas “A”.
Reconocimiento de patrones de diseño “composite”, sobre el conjunto de
programas “A”.
Reconocimiento de patrones de diseño “iterator”, sobre el conjunto de programas
“A
11
54
Cauítulo 5
Caso
4
5
6
I
8
9
10
11
12
EVALUACI~NEXPERIMENTAL
Plan O 1
Característica de Prueba
Reconocimiento de patrones de diseño “abstractfactory”, sobre un programa que
se sabe que incorpora el patrón de diseño “composite ”.
Reconocimiento de patrones de diseño “abstractfactory ”, sobre un programa que
se sabe que incorpora el patrón de diseño “iterator”.
Reconocimiento de patrones de diseño “composite”, sobre un programa que se
sabe que incorpora el patrón de diseño “abstractfactory”.
Reconocimiento de patrones de diseño “composite”, sobre un programa que se
sabe que incorpora el patrón de diseño “iterator”.
Reconocimiento de patrones de diseño “iterator”, sobre un programa que se sabe
que incorpora el patrón de diseño “abstractfactory”.
Reconocimiento de patrones de diseño “iterator”, sobre un programa que se sabe
que incorpora el patrón de diseño “composite ”.
Reconocimiento de patrones de diseño “abstract factory”, sobre el conjunto de
programas “B.
Reconocimiento de patrones de diseño “composite”, sobre el conjunto de
programas “B”.
Reconocimiento de patrones de diseño “iterator”, sobre el conjunto de programas
“R”
~~
5.5 Resultados de las pruebas
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; en los demás casos de prueba para
no repetir todas las pantallas de la herramienta, únicamente se muestra la pantalla de
resultados al buscar el patrón seleccionado en el código analizado. Los resultados obtenidos
de cada caso de estudio se describen a continuación:
55
EVALUACI~NEXPERIMENTAL
Capítulo 5
5.5.1 Caso de prueba 1
El primer caso se refiere a la detección del patrón de diseño abstractfactory en el
código que corresponde a dicho patrón:
1. En la figura 5.1 se muestra la pantalla principal de la herramienta, esta pantalla contiene
en el menú Archivo la opción Abrir.
.
~
i
~
.
,..
.. .,
__
.,
~~
..
~
.
...
~~
.... .
.
-
. .. .
l
Figura 5.1 Pantalla principal de la interfaz, mostrando opciones del
menú Archivo.
2. Al dar clic en la opción Abrir del menú archivo aparece la ventana de diálogo que
permite elegir el archivo que será analizado, figura 5.2.
Figura 5.2 Ventana de diálogo para abrir archivo fuente.
56
Capítulo 5
EVALUACI~NEXPERIMENTAL
3. Una vez elegido el archivo a analizar el sistema obtiene su forma canónica y otros
elementos de información del código como son las estructuras i f o switch, mostrándose
esta información en el panel correspondiente en pantalla, figura 5.3.
4. Después de seleccionar el archivo a analizar, se elige el patrón de diseño a detectar en el
código fuente. Desplegándose el resultado en el panel correspondiente, figura 5.4. En
este caso, el patrón es encontrado y con ello se muestran los nombres de las clases del
código que forman parte del patrón de diseño.
Figura 5.4 Resultado de buscar el patrón de diseño ubstructfuctory
57
EVALUACI~NEXPERIMENTAL
Capítulo 5
5.5.2 Caso de prueba 2
En el segundo caso de prueba se trató de reconocer el patrón de diseño composite en
el código que contiene este patrón. El resultado de éste caso de prueba fue positivo, como
se muestra
li..a
5.5.3 Caso de prueba 3
En esta prueba se buscó el patrón de diseño iterator en el código que contiene a
dicho patrón. El resultado de esta prueba fue positivo, como se muestra en la figura 5.6.
58
EVALUACI~NEXPERIMENTAL
Capítulo 5
En el siguiente conjunto de pruebas se verificó la existencia de patrones de diseño
en los códigos obtenidos de internet [CAS99], donde se buscó patrones de diseño para los
cuales no fueron construidos estos códigos, con el fin de verificar el comportamiento de la
herramienta. El resultado de estas pruebas se muestra a continuación.
5.5.4 Caso de prueba 4
En este caso de prueba, se buscó el patrón de diseño abstractfactory en el código
que contiene al patrón de diseño composite. El resultado obtenido es que el código no posee
relaciones del tipo ConcreteFactory, por lo tanto no se encuentra el patrón buscado, figura
5.7.
I
Figura 5.7'Resultado de buscar el patrón de diseño abstractfactory en el
código del patrón composite
5.5.5 Caso de prueba 5
En el quinto caso de prueba, se busca el patrón de diseño abstractfactory en el
código correspondiente al patrón de diseño iferator. Como se visualiza, el resultado es que
el código no posee relaciones del tipo Producto ni ConcreteFactory, por lo que no se
encuentra el patrón buscado, figura 5.8.
59
09
Capítulo 5
EVALUACI~NEXPERIMENTAL
5.5.7 Caso de prueba 7
En este caso de prueba, se busca el patrón de diseño composite en el código que
corresponde al patrón de diseño iferator.El resultado se ilustra en la figura 5.1O, el código
no posee
el
5.5.8 Caso de prueba 8
En este caso de prueba se busca el patrón de diseño iterator en el código que
corresponde al patrón de diseño abstructjiuctoy. El resultado se ilustra en la figura 5.11.
l r,.
~qi
~ : ~-. ~ . ~1 ~ ~ ~ , .
~
i
;
3
1
~
~~
~~~~
~~~~
Figura 5.11 Resultado de buscar el patrón de diseño iterator en el
código del patrón abstract factoly
61
Cauítulo 5
EVALUACI~NEXPERIMENTAL
5.5.9 Caso de prueba 9
En este caso de prueba se busca el patrón de diseño iterator en el código que
corresponde al patrón de diseño composite. El resultado de la presente prueba se ilustra en
la figura 5.12. El código no posee relaciones del tipo ConcreGAggregate por lo tanto la
herramienta no encuentra el patrón buscado.
Con el siguiente conjunto de pruebas se evalúa el comportamiento de la herramienta
al verificar la existencia de los patrones de diseño en el código de la tesis de maestría
[SAN941 tomada como prueba, esta no fue diseñada basándose en ningún patrón de diseño.
5.5.10 Caso de prueba 10
En este caso de prueba, se busca el patrón de diseño abstractfactory en el código de
la tesis de maestría tomada como prueba. El resultado de tal evaluación se muestra en la
figura 5.13, 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.
62
Figura 5.13 Resultado de buscar el patrón de diseño abstract factory en la
tesis de maestría
5.5.11 Caso de prueba 11
En este caso de prueba se busca el patrón de diseño composite en el código de la
tesis mencionada como caso de prueba. En la figura 5.14 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 Composite.
4 1
t i
..
-
'I
t
Figura 5.14 Resultado de buscar el patrón de diseño composite en la
tesis de maestría
63
'sopeqnsai ap laued
la ua s o p s a p sñ8aleils oyasip ap sauoqed ap oiauiyu [e apuodsauo:, B a j u ~ j ss e m ~ ~ t u p a
se1 ap Iamd lap op!ua)uoj [a 'opeprue Y J I ! M S 0 4 epe3 iod B a j u r j s ogas!p ap u q w d
un i!npu! apand as anb 'ipap apand as :o)ua!uiep!ue ap salayu sail ap s?ur u03 S,q3l!MS
o SJI seinptu)sa uei)uan3ua as !s opueq!iaA 'sa opa 'opuez!~eue sisa as anb 08!pp
lap o;ua!uiepoduroD le opiame ap opeilnsai la aua!iqo as eqatud ap ose3 aisa sa
'9I 'sein8rj 'Baju.qs
ogas!p ap sauoiied i!npu! iapod vied sepesa3au sasep se1 eilsanui eqanrd ap ose3 aisa
ap opqnsai 13 .L%JVJJS
seiq3wsa e i a ! 08!pq:,
~ ~
la anb 93snq as 'eqatud qsa u 2
eqanrd ap ose3 E I ~ S
'[66SV31
laiualur ap sopeceq soS!po:, so[ ua ogas!p ap sauoiled solsa ue3snq as sose3 s!as calua!&!s
so[ u 3 p o y j a u ajuiduaj sop opu&as la I( B a j u ~ j sseinptulsa oiauipd la :uaI(npu!
anb '++3ua sopeluauraldq sewei8oid aiqos oyas!p ap sauoqed so1 ap olua!tu!oouo3ai
1" uapuodsauo3 sose3 sop soiaurud so1 'poyjaut ajuiduaj X B a i u ~ j sogas!p ap sauoqed
so1 ap olua!urpouo3ai [a ienIeaa vied uoiez![eai as eqanrd ap sose3 saiua!@s so7
EVALUACI~NEXPERIMENTAL
Capítulo 5
Fimra 5.16 Resultado de buscar el natrón de diseño .stratem
5.5.14 Caso de prueba 14
En este caso de prueba, se buscó en el código que contiene el patrón de diseño
template method. El resultado de este caso de prueba es positivo como se ilustra en la
figura 5.17.
Figura 5.I 7 Resultado de buscar el patrón de diseño template method
65
I
Ill
5.5.16 Caso de prueba 16
En esta prueba, se buscó el patrón de diseño strategy en el código que contiene el
patrón de diseño iterator. El resultado
de este caso de prueba se ilustra en la fi ura 5 19
.
. ,, . ,
. . , . . ,~ . ; . ~ , , ~, . ; i . ~ ~ ~ ~ ~. .~ ~ ~ .. , . H f ' :
~~~
~~~~
~~~
,
~~~
~~~
~~
~~~
*hudlr"".nmimO:
roma i.n6nii~dslp*6nds~lirno
Figura 5.19 Resultado de buscar el patrón de diseño strategy en el
códieo del iterator
66
EVALUACI~NEXPERIMENTAL
Capítulo 5
5.5.17 Caso de prueba 17
código que
ilustra en la
Figura 5.20 Resultado de buscar el patrón de diseño strategy en el
código del comaosite
5.5.18 Caso de prueba 18
En el presente caso de prueba se evalúa la herramienta al buscar el patrón de diseño
template method en el código correspondiente al patrón abstractafactory. En la figura 5.21
c
P"mb* Aa*E,3ICION C<inrrnorecbm
IOREO*CION C o n r i s M s t l o ~
IOREO*CIONIPrndY'~*OREOIClON
IPrnd"noB. Canrrmsiridom HEREM
i
Figura 5.21 Resultado de buscar el patrón de diseño template method
en el código del abstract factory.
67
.
I
EVALUACI~NEXPERIMENTAL
Capítulo 5
el código
5.5.20 Caso de prueba 20
En este caso de prueba se evalúa la herramienta al buscar el patrón de diseño
templute method en el código correspondiente al patrón composite. En la figura 5.23 se
muestra el
-
~
_., . .--y
',I
-*I
~~~
~
~~~
~~~~~
.'
1
~
~
'
~~~
Figura 5.23 Resultado de buscar el patrón de diseño templute method
en el código del composite.
68
.
Capítulo 5
EVALUACI~NEXPERIMENTAL
5.6. Análisis de resultados
Como se ilustra en los casos de prueba aplicados a la herramienta, el
comportamiento de ella fue satisfactorio, ya que dio los resultados esperados de acuerdo al
análisis manual realizado a cada uno de los códigos que se probaron. Estos resultados
corresponden tanto a la obtención de la forma canónica del código fuente considerando la
gramática completa del lenguaje C++, como a los resultados en la detección de los patrones
de diseño, de los que se esperaba, como resultado que detectará el patrón de diseño buscado
en códigos en los que si se encontraba el patrón presente, la no detección en cuando el
código analizado no correspondía a alguno de ellos, aunque si informó que le faltaba para
corresponder al patrón de diseño buscado.
69
Capítulo 6
CONCLUSIONES
Capítulo 6
CONCLUSIONES
Este capítulo esta dedicado a las conclusiones obtenidas en el desarrollo de esta
tesis, se hacen comentarios acerca de los alcances logrados y se plantean algunos problemas
no resueltos que pueden ser temas de investigación para trabajos futuros.
70
Capítulo 6
CONCLUSIONES
6.1 Conclusiones generales
LOSpatrones de diseño capturan el razonamiento, atrás de soluciones probadas de
Y discute el balance entre Sus altemativas. El USO de patrones de diseño se está
fomentando en gran medida en la actualidad, y prueba de ello son 10s múltiples artículos
mcontrados en la literatura, en 10s cuales se piantea la solución de problemas usando
Pahones de diseño, sin embargo, la mayoría de herramientas actuales de ingeniería inversa
todavía son negligentes en la recuperación del razonamiento de diseño.
Como parte de esta tesis se.planteÓ ampliar los alcances del IPADIC++ mediante la
implementación de la gramática completa del lenguaje C++, en la formulación del modelo
canónico para representar las entidades de los programas escritos en C++.
AI finalizar el trabajo de investigación se pudo comprobar la hipótesis planteada al
inicio del trabajo. La implementación del reconocimiento de la gramática completa del
lenguaje C++ en la herramienta que implementa el modelo canónico de representación de
patrones de diseño, comprueba la hipótesis: Es posible la identificación automática de
patrones de diseño en código fuente, de la sintaxis completa'del lenguaje C++, a travis de
la implementación de un modelo de representación canónica tanto de los patrones de
diseño como del código fuente a analizar. En particular para este trabajo de tesis se
concluye que es posible la identificación automática de los, tres patrones de diseño
implementados en el IPADIC++, adicionalmente se reconocen por comportamiento
posibles strategy o template method de los patrones de diseño propuestos por.Erich Gamma
[GAM951 en código fuente escrito en C++.
De acuerdo'a las pruebas realizadas al sistema, se puede concluir que la herramienta
compila los programas escritos en lenguaje C++ de acuerdo a la gramática completa de este
lenguaje bajo el estándar ANSI-ISO, generando adecuadamente la forma canónica
correspondiente al código fuente analizado y 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, realizando tal detección en códigos fuente para los que se verifica la
gramática completa del lenguaje C++. Para la evaluación se definieron 20 casos de pmeba
y los 20 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.
6.2 Trabajos futuros
El presente proyecto de investigación realizó una parte más al trabajo de
investigación relacionado con patrones de diseño realizado en el área de Ingeniería de
Software del cenidet, sin embargo, es necesario seguir trabajando en la misma línea de
investigación para complementar esta investigación. Por lo que deben desarrollarse
trabajos futuros, como es:
En la implementación de los patrones de diseño planteados al inicio de esta tesis:
factory method, strategy y template method, por cuestiones de análisis sintáctico , no se
implemento en el sistema el reconocimiento del patrón de diseño factory method,
71
Capítulo 6
CONCLUSIONES
quedando pendiente para futuros trabajos realizar las reglas gramaticales que realicen el
reconocimiento de este patrón así como su implementación en la herramienta.
En la implementación del reconocimiento de la gramática del lenguaje C++ para
realizar la forma canónica del código fuente, se hace necesario incluir la implementación
del reconocimiento de las directivas de pre-procesamiento para el lenguaje C++.
Extender el sistema para la identificación de un mayor número de patrones del catálogo
de Gamma et. al. [GAM95], que son importantes en el desarrollo y administración de
marcos reusables de aplicaciones orientadas a objetos.
Construir otro sistema que sea capaz de distinguir a patrones propios de un dominio de
aplicaciones en particular.
En la herramienta, 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 UML,
OMT, o BOOCH, lo que haría más fácil para el usuario la interpretación del resultado;
ya que confrontaría de manera más legible y entendible el diseño del código analizado
con la estructura de los patrones de diseño buscados.
Que el sistema se extienda para que analice también código en otros lenguajes como
Java, Visual Basic, Delphi, etc.
A la fecha, la herramienta 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.
72
BIBLIOGRAFÍA
[AHR95]
Judith D. Ahrens, Noahs S. Prywes. “Transition to a legacy - and reuse
Based Software Life Cycle”. IEEE computer, October 1995, pp. 27 - 36.
[APP91]
Doris Appleby.”Programming Languages. Paradigm and practice”. Ed
McGrawHill. 1991,458 p.
[BAN981
Jagdish Bansiya.”Automating Design-Pattern Identification”. Dr. Dobb’s
Journal. http://www.ddi.cod.ddi/l998/1998-06/lead/lead.htm.
June 1998.
[BOS98]
Jan Bosh. ”Design patterns as language constructs” University of
KarlskronaRonneby, JOOP, mayo, 1998, pp. 18-25.
[BR097]
Brown, Kyle, “Design Reverse-Engineering and Automated Design Pattern
Detection
in
Smalltalk”.
Master
Thesis.
URL:
http://www2.ncsu.ed~eos/info/tasug/kbrow~thesis2.htm,
1997
[BUD961
F.J. Budinsky, M.A. Finnie, J.M. Vlissides and P.S. Yu, ”Automatic code
generation from design patterns”, IBM System Journal, Vol. 35, No. 2, 1996
- Object Technology.
[BUR951
Margaret Burneti et al (eds). “Visual Object - Oriented programming”
Concepts and environments. Manning Publications, 1995.
[CAM971
Marcelo .Campo, Claudia Marcos and Alvaro Ortigosa. ”Framework
comprehension and design patterns: a reverse engineering approach, in
Proc. Of the 19Ih. Int. Conf. On Sofhvare Engineering, SEKE’97, Madrid,
Spain, junio 1997.
[CAS991
Félix Agustín Castro Espinosa. “Sistema de identificaión de patrones de
diseño en código C++”. (Maestria en Ciencia en Ciencias Computacionales,
Cuemavaca, Morelos: Cenidet, 1999), p.87.
[CHAOO]
Craig Chambers, Bill Hamson and John Vlissides. ”A debate on language
and tool support for design patterns”, PLOPL 2000, Boston MA USA, ACM
2000.
[COO981
James W. Cooper. “User Interfaces That Vary with Your Data”. Fawcette
Technical Publications, junio/julio 1998
[FAY971
Fayad, M. E., Schmidt, D.C., and Johnson, R. E. ”Object-Oriented
Application Frameworks: Problems and Perspectives”. Wiley, NY, 1997.
-
73
[FAY971
Fayad, M. E., Schmidt, D.C., and Johnson, R. E. ”Object-Oriented
Application Frameworks”. Communications of the ACM, Vol. 40, No. 10,
October 1997, pp. 32-38. http://www.cs.unr.edu/-favad/frameworks,
[email protected], [email protected]
[FOS98]
Ted Foster and Hiping Zhao. ”Modelig Transport Objects with Patterns”
JOOP, enero de 1998. Pp. 26-32.
[FOW99]
Martin Fowler. Refactoring: Improving the Design of Existing Code.
Addison-Wesley, 1999.
[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, Jeffrey D. Ullman
Introducción a la teoría de automátas, lenguajes y computación
Compañía Editorial Continental, S. A. De C.V. 1993.
[JOH98]
Johnson R. E. and Foote, B. Designing reusable classes, J. Object-Oriented
programming. 1 , 5 (June/ July 1998).pp. 22-35.
[KEL99]
Rudolf K. Keller, Sébastien Robitaille, Reinhard Schauer and Patrick Pagé.
”Pattern- based reverse-engineering of design components”, Department
IRO, Univesité de Montréal, ICSE ’99 Los Angeles CA, ACM 1999.
pp.226-235
[KRA96]
Christian Kramer, Lutz Prechelt. “Design Recovery by Automated Search
for Structural Design Patterns in Object-Oriented Software”. Working
Conference on Reverse Engineering, IEEE CS Press, Monterey CA,
November 8-10, 1996.
[MAR961
Robed, Martin. “the Open-Closed Principle”. C++ report, enero de 1996.
[MIL951
Hafedh Mili, Fatma Mili y Ali Mili. “Reusing Software: Issues and Research
Directions”. IEEE Transactions on Software Engineering, Vol. 21, No. 6,
junio 1995.
[MET--]
Sitio de Metamata . “Javacc”. http://www.metamata.com/iavacc/
[NOV97]
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.
[SPI97]
Tom Spitzer, “Component Architectures DBMS”. September 1997,
pp. 56 - 66.
74
[PRE95J
Pree, w . (1995): Design Patterns
Development, Addison-Wesley.
[PRE98]
Charles Rich and Linda M. Wills. ”Recognizing a programming design a
graph-parsing approach”, Massachusetts Institute of Technology. IEEE
Software, enero 1990. pp. 82-89
[RIC90].
Charles Rich and Linda M. Wills. ”Recognizing a programming design a
graph-parsing approach”, Massachusetts Institute of Technology. IEEE
Software, enero 1990. pp. 82-89
[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 maestría, Morelos: Cenidet, mayo de 1994.
[SAN991
Rene Santaolaya Salgado, “Sistema de administración de componentes de
software basados en frameworks”, Proyecto 32042, Cuernavaca, Morelos:
Cenidet, 1999.
[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 Depament,
MD, 20742 USA. 1996.
[THO951
Dave Thomas
Component - Based Software Cosntrution:
Making the Transition from Crafi to Engineering First Class the Magazine
for Object Tecnology Professionals
February / march 1995, pp. 12 - 13.
[VIS961
Sreenivasa Viswanadha. “C++ grammar”.
for
Object-Oriented Software
http//falconet.inria.fr/Indexof/java/tools/JavaCC/examples/CandCPLUSPLU
S/, Sun Microsystems Inc.
[WAT97]
Sadakazu Watanabe. “Profesionalism through O 0 and Reuse”.
IEEE january 1997.
75
Anexo A
PATRONES DE DISEÑO
RECONOCIDOS EN LA TESIS
En este apéndice se muestra la información referente a los patrones de diseño
reconocidos en la tesis. La estructura de los patrones se ilustra en la notación OMT.
16
Patrón de diseño Abstract Factory
La intención del patrón abstract factrory es proporcionar una interface para crear
familias de objetos relacionados o dependientes sin especificar sus clases concretas.
La estructura del patrón abstractfactory se muestra en la figura A. 1.
Cliente
1
Fabricacancreta1
I
I
I
I
I
I
I
I
I
I
I
I
I
t
________
I
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:
'%lient ACQUAINTANCE apa ACQUAINTANCE af; af; cfl HEREDA af CREATES pa,
apa, p a l HEREDA apa"
77
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 uniformemente.
La estructura del patrón composite se muestra en la figura A.2.
I
I
Composite
~
Figura A.2. 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:
'%lientACQUAINTANCE Component, Component, Leaf HEREDA Component, Composite
HEREDA Component AGREGACION Component[n] "
78
Patrón de diseño Iterator
La intención del patrón de diseño iterator es proporcionar ia forma 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 A.3.
F
*
Aggregate
I
I
*
I
I
Figura A.3. Estructura del patrón de diseño iterator
La forma canónica del patrón de diseño iterator obtenida al aplicar el modelo
canónico para representación de patrones de diseño es la siguiente:
"Aggregate, ConcreteAggregate HEREDA Aggregate CREATES Concretelterator, Iterator,
ConcreteIterator HEREDA Iterator ACQUAINTANCE ConcreteAggregate
'I
79
Patr,.i de diseño Factory Method
La intención del patrónfactory method es definir una interface para crear objetos,
pero deja que las subclases decidan cual clase instanciar. Factory method deja a la clase
diferir instanciación a subclases.
La estructura del patrónfactory method se muestra en la figura A.4.
FactoryMethodO
Anoperation()* ...._.__
............
............
Product = FactoryMethod()
FactoryMethod() 0.'.' ~ ~ ' ' ' ' 'Return
~''~
new ConcreteProduct
Figura A.4 Estructura del patrón de diseñofactory method
La forma canónica del patrón de diseño factory method obtenida al aplicar el
modelo canónico para representación de patrones de diseño es la siguiente:
'Creator, Product, ConcreteCreator HEREDA Creator CREATES ConcreteProduct,
ConcreteProduct HEREDA Product"
80
Patrón de diseño Strategy
La intención del patrón strategy es definir una familia de algoritmos, encapsula cada
uno y los hace intercambiables. Strategy, deja que los algoritmos varíen
independientemente de los clientes que los utilizan.
La estructura del patrón strategy se muestra en la figura A S .
~
Context
Contextlnteríace()
3
ConcreteStrategyA
AlgorimiInterface()
Strategy
Algonmilnterfaz()
ConcreteStrategyB
AlgonmiInterface()
ConcreteStrategyC
Algontmlnterface()
La forma canónica del patrón de diseño strategy obtenida al aplicar el modelo
canónico para representación de patrones de diseño es la siguiente:
'Litrategy, Context AGREGACION Strategy, ConcreteStrategy HEREDA Strategy"
81
Patrón de diseño Template Method
La intención del patrón template method es definir el esqueleto de un algoritmo en
una operación, difiriendo algunos pasos a cada subclase cliente. Deja que las subclases
redefinan ciertos pasos de un algoritmo sin cambiar la estructura del algoritmo.
La estructura del patrón template method se muestra en la figura A.6
PrimitiveOperation2()
PrimitiveOperationl()
PrimitiveOperation2()
f
I
PnmitiveOperation 1()
PrimitiveOperation2()
Figura A.6 Estructura del patrón de diseño template method
La forma canónica del patrón de diseño template method obtenida al aplicar el
modelo canónico para representación de patrones de diseño es la siguiente:
"
Abstractclass, ConcreteClass HEREDA Abstract Class "
82
,
.
Anexo B
Códigos utilizados en la evaluación
extirimental
En este apéndice se muestran los archivos utilizados en la evaluación experimental,
en algunos de estos códigos se implementaron los patrones de diseño reconocidos en esta
tesis.
83
Código correspondiente al patrón Composite [CAS99].
/I*** Clase Component
#include <iostream.h>
class Component{
public: Component(){-next= NULL;}
virtual void operation(void) = O;
Component* getchild(void) const (return -next;)
virtual void setchild(Component* next) ( n e x t = next;}
virtual int compositeDetect() {retum(O);}
private:
Component* n e x t ;
1;
/I** Clase Composite
#include "component.hpp"
class Composite: public Component(
public:
Composite(int id)(-first = NULL; -identification = id;)
virtual void add(Component*);
virtual void removeLeaf(Component*);
virtual void removeComposite(Component*);
virtual void operation(void);
void operation(Component*);
virtual int compositeDetectO(retum(1);)
private:
int -identification;
Component* -first;
1;
void Composite::add(Component* c) {
c-setchildCfirst);//***************verificar
-fust = c;
I
void Composite::removeLeaf(Component*c) {
Component *t;
iKfirst =c){
-first = c-getchild();
c-setchild(0);
1
else{
for(t =-first; t; t = t-getchild()){
if(t-getchild() = c)
break;
84
..
.
....
void Composite::removeComposite(Component* c){
Component *t, *tnext;
if(c-compositeDetect()) {
for(t=((Composite *)c),first; t; t=inext)(
tnext = t-getchild();
t-setchild(0);
)
((Composite *)c)l-first = O;
1
void Composite::operation(void) {
if(_first) cout«"Composite: "«identification«endl;
1
void Composite::operation(Component* c) {
static int level =O;
Component "t;
for(int i=O; ¡<level; i+)(
COUf<<" I,;
)
c-operationo;
if(c-compositeDetect){
level++;
for(t=((Composite *)c)--first; t; t=t-getchild()) {
operation(t);
1
level-;
//*** Clase Leaf
#include "component.hpp"
class Leaf: public Component{
public:
Leaf(int id){-identification = i&)
virtual void cperation(void)
{ cout<<"Leaf: "«
-identification«endl;)
private:
int -identification;
};
//**Clase Cliente
#include "leaf.hpp"
#include "composite.cpp"
int main(void){
libreria a;
libreria *y;
Leaf 11 =new Leaf(-I);
Leaf 12 = new Leaf(-2);
Leaf 13 = new Leaf(-3);
Leaf 14 =new Leaf(-4);
85
. .
Leaf LI =new Leaf(1);
Leaf L2 = new Leaf(2);
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);
c 1.add(&ll);
cl.add(&IZ);
c2.add(&13);
c2.add(&14);
c3.add(&Ll);
c3.add(&L2);
cZ.add(&L3);
cZ.add(&cl);
c3.add(&c2);
c3.operation(&c3);
tout<<"
11;
c2.removeLeaf(&14);
c3.add(&14);
c3.operation(&c3);
tout<< I t ";
c2.removeComposite(&c I);
c3.operation(&c3);
retum(0);
1
86
Código correspondiente al patrón Abstract Factory [CAS99].
/I***Clase cliente
#include "d:\hodl\\ConcFacl .HPP"
#include "d:\hodl\\ConcFac2.HPP"
#include "d\\modl\\AProdA.HPP"
#include "d:\\modl\WrodB.HPP
void main0 {
ConcreteFactoryl Factory0 = new ConcreteFactoryl(0);
FactoryO.Prt0;
AProductoA ProdAO;
ProdAO = FactoryO.CreateProductoA(0);
ProdAO.Prt();
AProductoB ProdBO;
ProdBO = FactoryOCreateProductoB(0);
ProdBO.Prt();
ll(FactoryO.CreateProductA(0))->Prt();
//(FactoryO.CreateProductB(O))->Prt();
ConcreteFactory2 Factoryl =new ConcreteFactory2(1);
Factoryl .Prt();
AProductoA ProdAl;
ProdAl = Factoryl .CreateProductoA(l);
ProdAl.Prt();
AProductoB ProdB 1 ;
ProdBl = Factoryl.CreateProductoB(I);
ProdBl .Prt();
//(Factory 1.CreateProductA(l))->Prt();
//(Factory 1.CreateProductB( 1))->Prt();
} /I Termina Main.
/I** Clase AbsiractFactory
#ifndef A-Factory
#define A-Factory
class AProductoA;
class AProductoB;
class AbstractFactory {
public:
AbstractFactoryO
{ /I Vacia ...
}; // Termina constructor de la clase
virtual AProductoA *CreateProductA(int) = O;
virtual AProductoB *CreateProductB(int) = O;
}; // Termina clase AbsiractFactov.
#endif
87
I
!
/I***
Clase AproductoA
#ifndef A-Producto-A
#define A-Producto-A
class AProductoA {
public:
AProductoA()
{ I/ Vacía ...
); //Termina constructor de la clase
virtual void Prto = O;
); I/ Termina.AProductoA.
#endif
/I*** Clase AproductoB
#ifndef A-Producto-B
#define A-Producto-B
class AProductoB {
public:
AProductoBO
( // Vacía ...
}; // Termina constructor de la clase
virtual void Prt() = O;
); // Termina AProductoB.
#endif
Clase ConcreteFactoryl
#ifndef C-Factory1
#define C-Factory1
//*e*
.
#include <iostream.h>
#include "d\imodl\MbsFact.HPP"
#include "d:\\modl\\CProdAO.HPP"
#include "d:\imodl\\CProdBO.HPP"
class ConcreteFactoryl: public AbstractFactoiy . {
private: int Identificacion;
public:
ConcreteFactoryl(int ID) (Identificacion = ID; ); // Termina constructor
virtual AProductoA *CreateProductA(int);
virtual AProductoB *CreateProductB(int);
virtual void Prt(void)
{ cout << "ConcreteFactoryl: " << Identificacion << endl;
) // Termina la función Prt.
1;
AProductoA *ConcreteFactory 1::CreateProductA(int I)
( retum(new CProductoAO(1));
) // Termina CreateProductA.
AProductoB "ConcreteFactory 1::CreateProductB(int I)
{ retum(new CProductoBO(1));
) // Termina CreateProductB.
#endif
88
//*** Clase ConcreteFactory2
#ifndef C-Factory2
#define C-Factory2
#include <iostream.h>
#include "d\hodl\\AbsFact.HPP"
#include "d:\hodl\\CProdA 1 .HPP"
#include "d\hodl\\CProdB I .HPP"
class ConcreteFactory2: public AbstractFactory {
private:
int Identificacion;
public:
ConcreteFactory2(int ID) { Identificacion = ID; }; I/ Termina constructo1
virtual AProductoA *CreateProductA(int);
virtual AProductoB 'CreateProductBfint);
virtual void Prt(void)
{ cout << "ConcreteFactory2: " << Identificacion << endl;
} /I Termina,la función Prt.
};
AProductoA *ConcreteFactory2::CreateProductA(int I)
{ return(new CProductoAl(1));
} /I Termina CreateProductA.
AProductoB *ConcreteFactory2::CreateProductB(int I)
{ return(new CProductoBl(1));
} 11 Termina CreateProductB.
#endif
/I*** Clase CProductoAO
#ifndef C-Producto-A0
#define CProductoAO
#include "d:\hodl\WrodA.HPP"
class CProductoAO: public AProductoA {
.private:
int -1;
public:
CProductoAO(int I) { -1 =I; }; I/ Termina constructoi
virtual void Prt()
( cout << "ProductoAO: " << -1 << endl;
1;
}; I1 Termina CProductoAO.
#endif
/I*** Clase CProductoAl
#ifndef C-Producto-A 1
#define CProducto-A I
#include "d:\hodl\\AProdA.HPP"
class CProductoAl: public AProductoA {
89
I
I
I
private:
int -1;
public:
CProductoAl(int I) { -1 =I; }; /I Termina consmictor
virtual void Prt()
{ cout << "ProductoAl : " << -1 << endl;
1;
}; /I Termina CProductoAl
#endif
I/*** Clase CProductoBO
#ihdef CProducto-BO
#define C-Producto-BO
#include "d\\modl\\AProdB.HPP"
class CProductoBO: public AProductoB {
private:
int -1;
public:
CProductoBO(int I) { -1
- = I; }; //Termina constructor
virtual void Prt()
{ cout << "ProductoBO: " << -1 << endl;
}; // Termina CProductoBO.
#endif
//*** Clase CproductoBl
#ihdef C P r o d u c t o B 1
#define C-Producto-B 1
#include "d:\imodl\\AProdB.HPP
class CProductoB I: public AProductoB {
private:
int -1,
public:
CProductoBl(int I) { -1 = I; }; /I Termina consmictor
virtual void Prt()
( cout << "ProductoBi: " << -1 << end&
1
f ; I/ Termina
CProductoBl
#endif
90
Código correspondiente al patrón Iterator [CAS99].
I/*** Clase Iterator
template <class T>
class Iterator{
public:
virtual AggregateEntryQ* first() =O;
virtual AggregateEntryQ* next() = O;
virtual int isDone() = O;
virtual T currentItem() = O;
1;
/I*** Clase ConcreteIterator
#include "d\\cmm\\patrones\\iterator\\Iterator.hpp"
template <class T>
class ConcreteIterator : public Iterato-(
public:
ConcreteIterator(ConcreteAggregate<T>*);
virtual AggregateEntryQ* first();
virtual AggregateEnhycT>* next();
virtual int isDone();
virtual T currentItem0;
private:
ConcreteAggregate<D* -aggregate;
1;
/I*** Clase Aggregate
#include<iostream.h>
#include<string.h>
#include<assert.h>
template <class T>class Iterator;
template <class T x l a s s ConcreteIterator;
template <class Dclass ConcreteAggregate;
template <class 'D
class Aggregate{
friend class ConcreteIteratofiP,
public:
virtual I t e r a t o e * createIterator() const = O;
11...
);
template <class 'P
class AggregateEntry{
friend class ConcreteAggregateQ;
friend class ConcreteIteratofiT>;
public:
AggregateEntry(T value, AggregateEntry<T> *item){
val = value; n e x t = item;}
T ietvaiueo {returncvai);)
~~
~
private:
91
T -val;
AggregateEntry-
'next;
1;
/I*** Clase ConcreteAggregate
#include "d:\\cmm\\patrones\\¡terator\\Aggregate.hpp"
template <class D
class ConcreteAggregate : public Aggregate-{
friend class Concretelterator<T>;
public:
ConcreteAggregate() (aggregateEntry =-tail
-ConcreteAggregate() (remove();)
= O;)
void insert(T);
void append(T);
void remove();
int remove(T);
int length();
virtual I t e r a t o m * createherator() {retum(new ConcreteIterator());}
private:
AggregateEntry-*
aggregateEnhy;
AggregateEntryO* t a i l ;
92
Código correspondiente a la tesis de maestría [SAN94].
//El archivo se nombra "SAW.CPP" (Sistema Administrador de ventmas),
#include <graphics.h>
#include <bios.hz
#include "c:\kene\\pantallaI.Cpp"// "Pantalla" es una clase derivada de la clase "Lista".
int Tecla;
int gdnver = DETECT, gmode, errorcode;
void Setup();
// Menf principal.
void Edo-SysW(); /¡Menu principal,
void Edo-ASysW();
void EdoCreaWO;
void EdoACreaWO;
void Edo-EditWO;
void Edo-DragW();
void Edo-ASysW();
void Edo-CreaSg();
void Edo-ACreaSg();
void Edo-Fin();
.
main() { // RUTINA PRINCIPAL.
initgraph(&gdriver,&gmode,"C:\\TC\\BGI"); // modificado por gfm (directono de egavga.bgi)
errorcode = graphresult();
if (errorcode != grOk)
{ pnntf ("Error grafico: %sW',grapherrormsg(errorcode));
printf ("presiona una tecla para continuar: ");
getch();
exit( I);
) // if errorcode.
Pantalla Scr;
ScrSetUpO;
closegraph(); // Aqui regresa a modo texto ....
return O;
) // MM.
I*
#ifndef La-Pantalla
#define La-Pantalla
#include<bios.h>
#include<fstream.h>
#inclnde<math.h>
#include "c:\\rene\kegmentol .cpp"
#include "c:\\rene\\Mennsl .CPP"
//Definiciones de la clase mouse.
#include "c:\\rene\iMousel.CPP"
#include "c:\kene\\Cola 1.CPP"
#include "c:\\rene\\Listal .CPP"
extern Objeto V;
class.Pantalla: public Lista {
private:
unsigned Minx, MinY, MaxX, MaxY, MinWX, MinWY, MaxWX, MaxWY;
unsignedC1, TamX, TamY, NH, NV;
Menus Laspaletas, PaletasGrafs;
Boolean in-Area(unsigned Pxl, unsigned Pyl, unsigned Px2, unsigned Py2,
*I
93
unsigned Qxi, unsigned Qyl, unsigned Qx2, unsigned Qy2);
void SetGraTendík
void AddRes();
void DecRes();
protected:
public:
ClassMouse Mouse;
int Mx,MY; // Guardan la posici$n actual de las coordenadas de] M
~
~
~
PantaMunsigned NumV = 4, unsigned NumH = 3, unsigned Claro = 8) (
static Nodo *Apt;
Minx = O; MaxX = getmaxxo;
MinY = O; MaxY = getmaxy();
MinWX= MinX+ScrXI; MaxWX= MaxX-ScrX2;
MinWY= MinY+ScrYI; MaxWY= MaxY-ScrY2;
NH = NumH; NV = NumV, CI = Claro;
TamX = ((MaxWX-MinWX)+I -((NV+I)*CI))/Nv,
TamY = ((MaxWY-MinWY)+ I -((NH+i)*Cl))/”;
Apt = NULL;
Mouse.lni(O,O,getmaxx(),getmaxy());
} I/ Constructor de la clase Pantalla.
-Pantalla() ( } /I destructor
Boolean Vacia(); /I Funci$n que verifica la existencia de al menos una ventana.
void Set-Val(unsigned NumV = 4, unsigned NumH = 3, unsigned Claro= 8); I/ Set-Val.
11 Set-Actual.
virtual void Set-Actual();
void Set-Coord(unsigned x l , unsigned yl, unsigned x2, unsigned y2,Nodo *N);
void Desply();
I/ Desply.
void Refresca();
/I Refresca.
void Crea-V(unsigned X I , unsigned yl, unsigned x2, unsigned y2);
/I Crea objeto de clase Ventana.
void Crea-V(); /I Crea objeto de clase Ventana.
indicado.
void Get-Obj(Nodo *N); I/ Obtiene la E. de D. del nodo
void Dibuja-Obj(Nodo *N); /I Dibuja el objeto indicado.
void Abre-Obj(Nodo *N); 11 Abre al objeto indicado.
void Close-Obj(cbar *K); I/ Cierra el objeto indicado.
/I Funcién de arrastre de ventanas.
void Drag-V();
void Move-V(cbar *K); // Reubica la ventana indicada.
void Expand-V(char *K); /I Expande la ventana indicada.
void Contrae-V(char *K); 11 Contrae la ventana indicada.
void Set-C(char *K); // Ubica el cursor en la posici$n indicada.
void ONC();
/I Hace visible el cursor del mouse.
void OFFC();
/I Oculta el cursor del mouse.
Nodo *GetBoton(unsigned Px, unsigned Py); 11 Obtiene el bot$n apuntado porel Mouse.
11 Funci$n de ayuda del estado Setup.
void A-StUp();
void ACreaWO;
I/ Funci#n de ayuda del estado CreaW.
void -rag();
/I Funci$n de ayuda del estado Drag.
11 Funci$n de arranque del controlador de di logo.
void SetUpO;
11 Funcién de creacign de ventanas.
void CreaW();
11 Funci$n para almacenar en disco una pantalla.
void SaveSO;
/I Funcign para editar una ventana.
void EditWo;
11 funcign para redimensionar el area de una ventana.
void ReSizeW();
I/ Funci$n para recuperar desde disco una ventana.
void Restores();
11 Func$n para asociar una variable a una gr fica.
void SetVarW();
11 Funci$n para arrastrar por la pantalla una ventana.
void DragW();
11 Funci$n para reacomodar en mosaico una pantalla.
void Layoutso;
// Funci$n para refiescar una pantalla.
void RefresbS();
I/ Funci$n para asociar una gr fica de monitoreo a una ventana.
Nodo *SetSegWo;
\,I
~
.
,
94
..<.
void ONOFF-C();
// Funcién para prender o apagar el cursor.
void DelW();
I/ Funcién para borrar una ventana,
void FIN();
/I Funcién de fin de la sesi$n.
void Save-Scr(Pantalla Obj);
// Save-Scr.
' void Restore-Scr(Pantalla Obj);
// Restore-Scr.
//friend ostream &operator << (ostream &Str, Pantalla Scr);
//friend istream &operator >> (istream &Su, Pantalla &Scr);
) ; I /termina la clase Pantalla.
unsigned ContW = O;
unsigned Cx, Cy, ColorN, ColorXOR; I/ Variables globales para actualizar al objeto Px de clase Pix
I*
// archivo "Segmento.HPP".
#ifndef Segmentos.HPP
#define Segmentos.HrP
#include <graphics.h>
#include "c:\\rene\iDbLstl .CPP"
#include "c:\kene\Wodol . C P P
*/
class Segmento [
private:
Wxl, Wyi, Wx2, Wy2,Vxl, Vyl, Vx2, Vy2, NumW, UT, Time-Refr;
unsigned
Boolean
Visible;
Nodo*Din;
DbLst
Fix;
public:
Segmento(unsigned XI = O, unsigned Y 1 = O, unsigned X2 = getrnaxxo,
unsigned Y2 = getmaxy0, unsigned Q = O); // Constructor.
11 Destructor.
virtual -Segmento();
// Agrega.
void Agregapiodo *N);
// Agrega.
void Agregapiodo *Frst, unsigned);
I/ SMM.
void SMM();
void Smm();
I/ Smm.
void Actualiza();
>,
// Actualiza.
I/ Visual-ON.
void Visual-ON();
/I Visual-OFF.
void VisualOFFO;
// Redibuja todo el segmento.
void Redraw();
float GetXI();
float G e m ( ) ;
float GetY I();
float GetY2();
unsigned GetXpvLO;
unsigned GetXpvRO;
unsigned GetYpvTO;
unsigned GetYpvBO;
void SetXl(unsigned VarX);
void SetX2(unsigned VarX);
void SetYi(unsigned Vary);
void SetY2(unsigned Vary);
void SetXpvL(unsigned VarX);
void SetXpvR(unsigned VarX);
void SetYpvT(unsigned Vary);
void SetYpvBfunsigned Vary);
}; /I Termina la clase Segmento.
#endif
95
Código correspondiente al archivo prueIfAn.cpp, para evaluar el patrón de diseño
strategy.
//archivo prueIfAn cpp
int a=l, b=l, c=l, d=l, e=l, 6 1 , g=l, h=l, j=i, k=l, i=o;
int main(void){
if(4 {
cout<<"probando";
cout<<"if( a)"<<"h";
I
else if(b) {
while (i<=4) {cout<<''["<<i<<''] "; i t t ; }
if(c) cout«"probando if(c) h";
if(d) cout«"probando if(d) ui";
cout«"esta en if(b), paso if(c), salio de if(d)";
1
else if(e) {
i=O;
while(i<=3) {cout<<"["<<i<<"]"; i++;}
if(0 cout«"probando if(f)";
cout<<"esta en if(e), paso while, salio de if(0";
I
i=O;
do
cout<<"["<<i<<"] " ;
itt;
}while(i<=3);
if(g) cout<<"probando if(g)";
else if(h) cout<<"probando if(h)";
else if(i) cout<<"probando if(i)";
else ifíj) cout<<"probando ifíj)";
else if(k) cout<<"probando if(k)";
else cout«"probando else de if(k)";
retum(0);
I
........................................................................
96
Código correspondiente al patrón Template method.
// archivo prueTM.cpp.
#include ciostream.h>
#include cstring.h>
class ordenamiento (
int array[iO] ;
public:
void inicia ( 1 ;
void leer ( 1 ;
virtual void ordenar0 = O ;
void imprimir( ) ;
//otro template
void TM2 0 ;
voAd opPriml() ;
virtual void 0pPrim2 ( ) = O ;
void opPrim3 O ;
) ; //fin clase ordenamiento
void ordenamiento::iniciaO(
leer0;
ordenar ( ) ;
imprimir ( ) ;
I
void ordenamiento::leerO[
int i=O;
for (i=o; i<io; i++)[
coutcc"\n,["c<i< < " I " ;
tin>> array[il ;
1
1
void ordenamiento::imprimirO[
int i=O;
for (i=O; i<10; i++)
cout<<'l\n[r'cci
<<"I " < c array[il
;
I
void ordenamiento:: TM2 ( ) {
opPrim1.I) ;
opPrim2 O ;
opPrim3 ( ) ;
1
void ordenamiento::opPrimlO(
cout<c" operacion primitiva 1";
)
void ordenamiento::opPrim30(
coutc<" operacion primitiva 2 " ;
I
class burbuja:public.ordenamiento(
public:
void ordenar ( ) ;
void opPrim2 ( ) ;
} ; //€in clase burbuja
void burbuja: :ordenar0 (
int i, j, aux;
c o u t < < " ~ RBIJRBUJA'~;
~.
97
'
for (i=ü; i<g; i++) (
aux=array[il ;
for(j=i+i; j < l O ; j++)'
if (array[i]>array[j])(
aux=array [il ;
arrav[il= arraviil;
void burbuja: :opPrim2O (
tout<<" operacion primitiva
)
2
de burbuja";
class shel1:public ordenamiento{
public:
void ordenar ( ) ;
void opPrim2 ( 1 ;
) ; //fin clase shell
void shel1::ordenarO {
int aux=lO;
Coutcc'aORD.SHELL Prueba" ccaux;
void shell : : 0pPrim2 ( ) [
tout<<" operacion primitiva 2 de shell";
class norma1:public ordenamiento[
public: ,
void ordenar0 ;
void opPrim2 ( ) ;
) ; //fin clase normal
void norma1::ordenarO {
int aux=lO;
COutc<"ORD. NORMAL Prueba" c<aux;
)
void normal : :opPrim2( ) [
coutc<" operacion primitiva
2
de normal";
main0 (
char opcion='x';
while (opcion ! = ' s o ) (
coutcc"e1ije ordenamiento:\n";
cout<<"a) burbuja\n";
cout<<"b) shell\n";
tout< c c ) normal\n";
cout<< s ) salir\n" ;
cinzzopcion;
if (option=='a')
burbuja ord;
else if (opcion=='b')shell ord;
else if (opcion=='c')normal ord;
else if (opcion=='s')return(0);
else coutcc"debes teclear: a, b, c O s.\n";
ord.inicia();
) //fin while
coutc c " * * * * * * PROBANDO SWITCH * * * * * * \n '' :
opcion='x';
I'
'(
98
while íopcion ! = ' s ' l (
coutcc"e1ije operación prim. 2:\nl';
cout<< a ) burbuja\n " ;
coutcc"b1 shell\n";
coutcc"c1 normal\n,';
cout<c"sl salir\n";
cin>>opcion;
switch (opcion](
case ,'a':
burbuja ord;
break;
case 'b':
shell ord;
break;
case ',ct
:
n o n a 1 ord;
break;
case ' s ' :
return ( 0 1 ;
default: coutcc"debec teclear: a, b, c ó c . . .\n";
) //switch
ord.opPrirn20;
) //fin while
return ( 0 1 ;
I'
//€in main0
99
Anexo C
FUNCIONAMIENTO DEL SISTEMA
Como se mencionó en el capítulo 4 la interfaz del sistema tiene un menú que cuenta
con tres opciones, en este anexo se muestran las pantallas correspondientes a las opciones
de menú y se describe el funcionamiento de la interfaz del sistema.
1O0
El menú consta de tres opciones principales que son Archivo, Detección y Ayuda.
El menú de Archivo mostrado en la figura C.1, es para el manejo de archivos escritos en
lenguaje C++, tiene las opciones de Abrir, Cerrar y Salir.
Forma canónica de código fuente
Abrir
Salir
i
.ir;
Cerrar
..~-~-.-
.-
t
L
i
i
:,
Figura C. 1 Opciones del menú Archivo
AI elegir la opción Abrir del menú de Archivo se muestra una ventana de diálogo,
figura C.2, donde se elige el archivo a analizar. El archivo se analiza y además, se tiene un
seguimiento de todos los archivos que forman parte del código.fuente, mediante el uso de la
directiva de pre-procesamiento #include, para juntar el contenido de todos los archivos en
un sololistado.
Figura C.2 Ventana de diálogo para seleccionar archivo con extensión cpp
A continuación, se muestra el listado de los archivos que forman parte del código
fuente, la forma canónica del código fuente, las estructuras ifanidadas con más de tres
niveles o switch con más de tres casos, en caso de que los haya, los métodos plantilla de las
funciones en caso de que haya alguno en las áreas de texto correspondientes. Se activa la
opción Detección del menú principal permitiendo seleccionar el patrón de diseño a detectar
en el archivo elegido, figura C.3.
101
IIAWHNO: C z p a t r o n e s ~ s t r a c t F a c t o ~ , ~ ~
#include "c:iipatmnesiv\bstractFacto~iCon<
Métodos Plantilla en clases
Resultado de la detección
Figura C.3 Contenido de paneles después de elegir el archivo a analizar
En caso de que se elija un archivo que contenga errores sintácticos, el analizador
sintáctico de la gramática del lenguaje C++ muestra el error correspondiente en el panel de
forma canónica del código fuente, figura C.4.
Archivo
1
Deieccion Ayuda
Código fuente
Forma canónica de códiuo fuente
Rela
UARCHIVO: CIpruebaslord-sw.cpp
#Include 4ostream.hz
#include <string.hi.
class ordenamiento (
public:
array[l O];
public:
void ieero;
virtual void ordenarO=O;
void imprimiro;
1; Ilfin clase ordenamiento
Figura C.4 Contenido de panel de forma canónica del código fuente si hay error
sintáctico en el archivo analizado.
102
Una vez que se elige el patrón de diseño a detectar en el código fuente, se realiza la
detección y se muestran los resultados en las áreas de texto correspondientes, figura C.5
Arch%
Mesdon A m a
Forma canónica de Lód1mfUenie
Relaciones del cód can lib
Figura C.5 Pantalla resultante al elegir un patrón de diseño a detectar
El menú de Detección es para elegir el patrón de diseño a buscar en el código
seleccionado previamente con la opción Abrir del menú Archivo. En esta opción se
clasifican de acuerdo al catálogo de Gamma, cada uno de los patrones de diseño por medio
de tres submenús ilustrados en las figuras C.6, C. 7 y C.8.
"archivi\
P. Estructurales
#include
class Component(
public:
ComponentOLnext EJ"L;)
Figura C. 6 Submenú para patrones creacionales del menú detección
103
ComponentO(-next = NULL;)
Figura C. 7 Submenú para patrones de comportamiento del menú detección
/ICódigo $1 P.
-
Forma canónica de códiao fuente
P. Comporiamiento b
komponent, prueba1 AGREGACION Leaflnl
~GREGACION~ompiisite[nl,Component
~CCCIUAINTANCE
Conmonent. comnosite
l~cipy;,;omponent{
Camponento(-next=
Figura C.8 Submenú para patrones estructurales del menú detección
El menú de Ayuda contiene tres opciones mostradas en la figura C.9, cada una de
estas opciones despliegan una ventana de diálogo que muestra información acerca del
sistema y de los patrones de diseño (figuras C.10, C.11 y C.12).
Forma canónica de código fuente
Figura C.9 Opciones del menú ayuda
!
104
I
/\Esta herramienta realiza la detección de Patrones de Diseno en código fuente escrito en C++.
Debes elegir primero la opción abrir del menu Archivo para seleccionar el código fuente a analizar
Visualizarás en pantalla dentro del área de texto correspondiente el código fuente y su forma canónica
posteriormente puedes elegir el patrón de diseño que desees detectar en el código fuente, eligiéndolo
de los submenus correspondientes en el menu Detección; si deseas analizar otro código fuente cierra
el código fuente activo con la opción cerrar del menu Archivo
lroi(l
...........
il
.~
Figura.C.10 Ventana de diálogo de contenido del sistema
Un patrón de diseño nombra, abstrae e identifica ¡os 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
il
responsabilidades.
..........
. . .
1
.
Figura C.11 Ventana de diálogo de patrones de diseño
CENTRO NACIONAL DE INVESTIGACiÓN Y DESARROLLO TECNOLÓGICO
Herramienta para detección de patrones de diseño en código fuente C++
Elaborado por: L.I. Patricia Zavaleta Carrillo
Maestría en Ciencias en Ciencias Computacionales
It
...........
,.
Figura C.12 Ventana de diálogo de Acerca de ...
105'
Descargar