Download Anexos - Cenidet
Document related concepts
no text concepts found
Transcript
SEP SEIT DGIT CENTRO NACIONAL DE INVESTIGACIÓN Y DESARROLLO TECNOLÓGICO cenidet Herramienta de Modelado Visual Orientado a Objetos para la Generación Automática de Código en Java. T E S I S QUE PARA OBTENER EL GRADO DE MAESTRO EN CIENCIAS COMPUTACIONALES P R E S E N T A: JOSÉ ALBERTO MORALES MANCILLA DIRECTOR DE TESIS: DR. MÁXIMO LÓPEZ SÁNCHEZ CUERNAVACA MORELOS NOVIEMBRE DE 2008 Resumen La generación de código es una necesidad para la mayoría de los programadores que desarrollan software, por lo que existen numerosas herramientas CASE que permiten generar código en diferentes lenguajes a partir de modelos [19], por lo que el tema del presente trabajo es la aplicación de la ingeniería directa para generar código en lenguaje Java a partir del diagrama de clases utilizando la notación del UML. Las herramientas CASE que existen y usan ingeniería directa para generar código a partir de los diagramas de clases, presentan una peculiar limitación, no permiten generar código de los métodos de las clases, por lo que han dejado a un lado la generación del diseño detallado de los métodos. Se pretende que SOODA que es una herramienta de software que genera código en lenguaje C a partir de modelos con diagramas de clases, sea capaz de generar código en Java para el diseño detallado de los métodos, apoyándose de una herramienta de software llamada DDVi que genera código de los métodos en lenguaje C. Por lo tanto el objetivo del presente trabajo de tesis debido a la limitación de las herramientas CASE existentes, es la generación de código en Java a partir de diagramas de clases y la generación de código en Java para el diseño detallado de los métodos de las clases a partir de los diagramas de Warnier. Los diagramas de clases del UML y los diagramas de Warnier, serán la notación base a partir de los cuales se podrá generar código en lenguaje Java. Los diagramas de clases y los diagramas de Warnier deben tener correspondencia con los respectivos códigos generados. Para ello se realizaron pruebas que permitieron comparar los códigos generados automáticamente con sus diagramas utilizando el código fuente de un modelo de un sistema de un cajero automático del cual se modelaron algunos métodos de las clases que lo integran. Los métodos seleccionados contienen estructuras de control secuencial, repetitivo y de selección. También se realizaron pruebas sobre el código generado automáticamente para verificar errores de sintaxis mediante el IDE de desarrollo JCreator. Palabras clave: Generación de código automático, diagramas de clases de UML, CASE, diagramas de Warnier, SOODA, DDVi, generación de código en Java. x Abstract Code generation is a need for most programmers who develop software, that’s why there are a lot of CASE tools that make it possible to generate code in different languages from models [19]. The topic of this work is the application of direct engineering to generate code in Java language from the classes diagram using UML notation. Actual CASE tools that make use of direct engineering for code generation from class diagrams, present a peculiar limitation: they are unable to generate code from the methods of the classes, leaving besides the generation of the detailed design of the methods. The objective is that SOODA that is a software tool that generates code in C language from models with classes diagrams, be able to generate code in Java for the detailed design of the methods, having support of a software tool called DDVi that generates code from the methods in C language. Given the limitation of actual CASE tools, the purposes of this thesis work is code generation from classes’ diagrams and the generation of code in Java for the detailed design of the methods of the classes from the Warnier diagrams. UML Classes diagrams and Warnier diagrams are the base notation from which it is possible to generate code in Java language. Classes’ diagrams and Warnier diagrams must be equivalent with generated code. Several tests were performed for that purpose that allow us make comparisons between the codes automatically generated with the diagrams using the source code from an automated cashier system model from which some of the classes methods were modeled. The selected methods have sequential, repetitive and selection control structures. Additional tests were performed on the automatically generated code in order to verify syntax errors using the IDE of the develop JCreator. Key words: Automated generated code, UML class diagrams, CASE, Warnier diagrams, SOODA, DDVi, generation of code in Java xi Anexo A: La MFC y Windows ______________________________________________________________________ ANEXO A: La MFC y Windows CONTENIDO Introducción La interfaz basada en llamadas de Windows Bibliotecas dinámicas de enlace (DLL) Procesamiento de mensajes Mapas de mensajes Macros de mensaje Mapas de mensaje y las macros Agregación de manejadores de mensaje a la clase Contextos de dispositivo Arquitectura documento/vista Función GetDocument Función OnDraw 103 Anexo A: La MFC y Windows ______________________________________________________________________ Introducción La MFC es un sistema de clases C++ diseñado para facilitar y agilizar la programación de Windows. La MFC consiste en una jerarquía de clases de multicapas que definen aproximadamente 200 clases. Estas clases permiten construir una aplicación de Windows utilizando principios orientados a objetos. La MFC ofrece la ventaja de código reutilizable, donde las aplicaciones pueden heredar la funcionalidad de la MFC. Otro modo en que la MFC simplifica la programación de Windows es la organización de la Interfaz de Programación de Aplicación de Windows, por sus siglas en inglés API. Los programas de aplicación se relacionan con Windows a través de la API. Las MFC encapsulan gran parte de la API en un conjunto de clases, por lo que son más fáciles de manejar [9]. Algunas clases definidas por la MFC no se relacionan directamente con la programación de Windows, es el caso de algunas clases de MFC que se utilizan para el manejo de cadenas, archivos y manejo de excepciones, a estas clases se les conocen como de propósito general, pueden utilizarse o no en programas de Windows. La interfaz basada en llamadas de Windows Windows utiliza una interfaz basada en llamadas para acceder al sistema operativo. La interfaz basada en llamadas de Windows es un conjunto de funciones del sistema que llevan a cabo actividades relacionadas con el sistema operativo, tales como reservar memoria, salida a pantalla, creación de ventanas, etc.. Estas funciones se llaman Interfaz de Programación de Aplicación o API. Los programas de aplicación invocan a las funciones API para comunicarse con Windows. La MFC encapsula la API e interactúa con ella a través de las funciones miembro de la MFC. Bibliotecas dinámicas de enlace (DLL) Las funciones API de Windows están contenidas en Bibliotecas dinámicas de enlace o DLL, a las que cada programa de aplicación tiene acceso cuando se ejecuta. Durante la fase de compilación cuando el programa invoca una función API, el enlazador no añade código a la función del código ejecutable del programa. Cuando se ejecuta el programa, se cargan únicamente las rutinas API necesarias mediante el cargador de Windows. Es decir, cada programa de aplicación no necesita tener el código API, ya que las funciones API se cargan sólo cuando se carga una aplicación a la memoria para su ejecución. Procesamiento de mensajes Windows se comunica con las aplicaciones enviándoles mensajes. Existe una variedad de mensajes y cada mensaje se representa con un valor de tipo entero único. En el archivo de cabecera WINDOWS.H están los nombres estándar para el manejo de los mensajes. Algunos mensajes son, WM_CHAR, WM_PAINT, WM_MOVE, WM_LBUTTONUP, 104 Anexo A: La MFC y Windows ______________________________________________________________________ WM_LBUTTONDOWN, WM_COMMAND. Cada vez que se produzca un evento que nuestra aplicación deba contestar, se envía un mensaje que identifique a ese evento [9]. Mapas de mensajes La MFC proporciona el mecanismo para el manejo de mensajes que la aplicación puede implementar, las cuales son funciones para el manejo de los mensajes; si la aplicación implementa un manejador, se invoca la función correspondiente para el manejo del mensaje. Si el mensaje lleva información asociada, esta se pasará al manejador como un argumento. Cuando la aplicación responde a un mensaje se ejecutan tres acciones: 1. La macro de mensaje que corresponde al mensaje se debe agregar al mapa de mensajes de la aplicación. 2. El prototipo para el manejador de mensaje se debe añadir a la clase de ventana que procesará el mensaje. 3. Se debe implementar el manejador de mensaje asociado con el mensaje. Macros de mensaje Para que la aplicación responda a un mensaje, la macro de mensaje correspondiente al mensaje se debe agregar en el mapa de mensaje de la aplicación. Las macros de mensaje de la MFC tienen el mismo nombre que los mensajes de Windows, la diferencia es que las macros de mensaje inician con ON_ seguido de paréntesis, por ejemplo para el mensaje WM_PAINT, la macro sería ON_WM_PAINT, para el mensaje WM_MOVE, la macro sería ON_WM_MOVE, en el caso del mensaje WM_COMMAND la macro sería ON_COMMAND la cuál es la única excepción a la regla. Mapas de mensaje y las macros Para agregar una macro de mensaje al mapa de mensaje, solo se debe incluir entre BEGIN_MESSAGE_MAP y END_MESSAGE_MAP. Por ejemplo para que la aplicación procese los mensajes WM_LBUTTONUP y WM_LBUTTONDOWN se agregan las macros de mensaje al mapa de mensajes, de la siguiente manera: BEGIN_MESSAGE_MAP(CMainWin, CFrameWnd) ON_WM_LBUTTONUP() ON_WM_LBUTTONDOWN() END_MESSAGE_MAP() Por tanto la aplicación ahora podrá procesar estos mensajes. 105 Anexo A: La MFC y Windows ______________________________________________________________________ Agregación de manejadores de mensaje a la clase Para que la aplicación pueda responder a un mensaje, debe asociarse el mensaje a un manejador de mensajes. El nombre de la función para el manejo de mensajes, utiliza el nombre del mensaje precedido de On, por el nombre de la función manejadora del mensaje WM_LBUTTONDOWN es OnLButtonDown() [9]. Para que la aplicación responda al mensaje, se debe agregar el prototipo en la declaración de la clase de ventana que esta en la aplicación. Por ejemplo el manejador OnLButtonDown se agrega a la clase CMainWin. Class CMainWin : public CFrameWnd { public: CMainWin(); afx_msg void OnLButtonDown(); DECLARE_MESSAGE_MAP(); } Todas las funciones manejadores de mensajes utilizan el especificador afx_msg. Ahora OnLButtonDown() es parte de la clase y responderá a los mensajes WM_LBUTTON_DOWN. Contextos de dispositivo Un contexto de dispositivo es una estructura que describe el entorno de visualización de una ventana, el cual incluye el controlador de dispositivo y los parámetros de visualización. Las clases del contexto de dispositivo de la MFC, encapsulan el proceso para el manejo de la visualización, por ejemplo cuando se instancia un objeto de la clase CClientDC, se obtiene un contexto de dispositivo para el área del cliente que requiera hacer un impresión a pantalla. Arquitectura documento/vista La MFC separa los datos y de cómo se visualiza, para ello usa dos clases; la clase CDocument para los objetos que almacenan los datos y la clase CView para visualizar los datos. La visualización puede presentar texto o gráficos en pantalla. El documento sirve como medio para guardar los datos obtenidos de otro sitio como por ejemplo: los de una base de datos. Cada objeto de documento de una aplicación documento/vista de la MFC está asociado con uno o más objetos derivados de la clase CView que proporciona la MFC. Una vista es una ventana, sin un marco, aparece sobre la parte superior del área del cliente de la ventana del marco principal. El objeto vista sirve para visualizar los datos del documento. La razón principal de la arquitectura documento/vista es poder visualizar diferentes vistas del mismo documento al mismo tiempo. La MFC proporciona un mecanismo para poder actualizar las vistas cuando cambia cualquier vista simple, para ello 106 Anexo A: La MFC y Windows ______________________________________________________________________ se invoca a la función miembro CDocument::UpdateAllViews, que sirve para actualizar al mismo tiempo todas las vistas [3]. Función GetDocument La función GetDocument sirve para que la clase vista pueda obtener un apuntador a la clase documento, ya que es responsabilidad de la vista presentar los datos del documento. Mediante este apuntador la vista permite invocar funciones miembro de la clase documento y acceder a cualquier variable del documento, las siguientes líneas de código ejemplifican más este proceso, suponiendo que la clase documento se llama CMyDrawDoc [3]. CMyDrawDoc *pDoc = GetDocument(); Función OnDraw Es una función que a pesar de su nombre se parece a los manejadores de mensajes, no maneja directamente los mensajes y no se agrega al mapa de mensajes. Es en esta función donde se realizan los dibujos en una aplicación basada en la arquitectura documento/vista de MFC. Las siguientes líneas de código muestran esta función OnDraw, suponiendo que la clase vista se llama CMyDrawView. void CMyDrawView::OnDraw(CDC* pDC) { CMyDrawDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); } Como se observa, se obtiene un apuntador al documento llamando a la función GetDocument, precisamente es aquí donde se dibujan los datos del documento. 107 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ ANEXO B: Jerarquía de clases de la MFC. CONTENIDO Jerarquía de clases de la MFC Clases de la arquitectura de una aplicación Clase del objeto de aplicación Clases para plantillas de documentos Clase de documento Clases para el soporte de ventanas Clases para el soporte de ventanas marco Clases para el soporte de vistas Clases para el soporte de ventanas de diálogo Clases para el soporte de controles Clases para el soporte de gráficos. Clases para el dibujo de gráficos Clases para el manejo de colecciones Plantillas para colecciones Diagrama de clases de la MFC 108 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ Jerarquía de clases de MFC La biblioteca de clases base de Microsoft de la MFC por sus siglas en inglés Microsoft Foundation Classes es una interfaz orientada a objetos que permite desarrollar aplicaciones para Windows. SOODA y SCUML basaron su desarrollo con la MFC, por lo que es importante conocer como esta construida. Las clases que proporciona la MFC se pueden clasificar de la siguiente manera y su jerarquía se muestra en la figura B1. CObject Clases no derivadas de CObject API para el servidor de internet Clases de soporte Modelo de objeto y serialización Plantillas para colecciones Soporte de sistema Tipos de datos varios Soporte OLE Colecciones Estructuras Sincronización Arquitectura de la aplicación Soporte gráfico Figura B1 Jerarquía de clases de la MFC. Por cuestiones de simplicidad y espacio, únicamente se explicarán sin mayor detalle, algunos grupos de clases y clases principales de la MFC, porque son clases que forman parte del sistema desarrollado. CObject: Es una clase abstracta y es la clase raíz de la jerarquía de clases de la biblioteca MFC, proporciona varios servicios útiles como soporte de diagnóstico para ayudar a depurar, creación y borrado de objetos, soporte para serialización (guardar y recuperar objetos), información de tiempo de ejecución para determinar la clase de un objeto. 109 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ Clases de la arquitectura de una aplicación Las clases que intervienen en la arquitectura de una aplicación, están todas derivadas de la clase CCmdTarget. Un objeto CCmdTarget es un objeto que tiene un mapa de mensajes y puede procesarlos. Este conjunto de clases incluye clases de objetos aplicación, clases de plantillas de documentos, clases de documentos, clases de elementos de documentos, clases de ventanas y otras clases [6]. La figura B2 muestra la arquitectura de una aplicación, CCmdTarget: Esta clase permite manejar mapas de mensaje de Windows. Cualquier clase derivada de CCmdTarget puede manejar su propio mapa de mensajes, esto permite que cada clase maneje de la forma en que lo desee, los mensajes en los que tenga interés. CCmdTarget Objeto aplicación Plantillas de documentos Documentos Soporte de ventanas Figura B2 Arquitectura de una aplicación. Clase del objeto de aplicación La clase del objeto aplicación representa procesos e hilos. Cada aplicación en el marco de trabajo de las MFC tiene un objeto de aplicación de una clase derivada de CWinApp [6]. La figura B3 muestra la arquitectura de clases de una aplicación. 110 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ CWinThread CWinApp Aplicación del usuario Figura B3 Arquitectura de un objeto aplicación. CWinThread; Esta clase define un hilo de ejecución para la aplicación y proporciona soporte para la multitarea mediante el uso de subprocesos basada en hilos, lo cuál provoca que se puedan ejecutar varias tareas al mismo tiempo. CWinApp: Esta clase encapsula la aplicación basada en la MFC, controla el arranque, la inicialización, ejecución creación de su propia ventana, operación de un bucle de mensaje para obtener mensajes desde el sistema operativo de Windows y distribuirlos a las ventanas del programa, cierre de la aplicación y hacer limpieza después de la aplicación. Clases para plantillas de documentos Una plantilla de documento, describe la relación del documento definido por el usuario y las clases de vista utilizadas para mostrar el documento [6]. MFC utiliza las plantillas de documento para crear y administrar la ventana de aplicación, documento y objetos vista. La figura B4 muestra la arquitectura de la plantilla de documento. CDocTemplate CSingleDocTemplate CMultiDocTemplate Figura B4 Arquitectura de una plantilla de documento. 111 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ CDocTemplate: Es una clase base abstracta que define la funcionalidad básica para las plantillas de documento. Por ser una clase base abstracta, no se puede utilizar directamente. CSingleDocTemplate: Esta clase define una plantilla de documento que implementa una Interfaz Sencilla de Documento, por sus siglas en inglés SDI (sólo un documento puede ser abierto a la vez). CMultiDocTemplate: Esta clase que define una plantilla de documento que implementa una Interfaz Múltiple de Documentos, por sus siglas en inglés MDI (varios documentos pueden estar abiertos a la vez). Clase de documento Un documento representa una unidad de datos que el usuario puede abrir, manipular y guardar. Los objetos documento que guardan los datos del usuario están relacionados estrechamente con los objetos vista que presentan dichos datos en pantalla. Cada aplicación en el marco de trabajo de las MFC, tiene al menos un objeto documento derivado de la clase CDocument. La arquitectura se muestra en la siguiente figura B5. CDocument Documento del usuario Figura B5 Arquitectura de la clase documento. CDocument: Esta clase proporciona la funcionalidad para las clases documento definidas por el usuario. Un documento es un objeto para almacenar los datos de un usuario, el puede abrir y guardar los datos usando el menú Archivo. Clases para el soporte de ventanas Las ventanas son objetos receptores de mensajes, y proporcionan soporte para muchos tipos de ventanas tal como, ventanas marco, vistas, ventanas de diálogo, controles, barras de control y hojas de propiedades. La clase CWnd encapsula la funcionalidad de todas las ventanas. La arquitectura para el soporte de ventanas se muestra en la figura B6. 112 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ CWnd Ventanas marco Vistas Ventanas de diálogo Controles Figura B6 Arquitectura para el soporte de ventanas. CWnd: Esta clase es la base de la que se derivan todas las clases de ventanas, ya que proporciona el soporte para el manejo de todos los tipos de ventanas. Clases para el soporte de ventanas marco En la librería de la MFC están definidas las clases CFrameWnd para aplicaciones SDI (Interfaz Sencilla de Documento) y CMDIChild y CMDIFrameWnd para aplicaciones MDI (Interfaz Múltiple de Documento). La ventana marco en una aplicación SDI es la ventana principal, sólo hay una ventana marco, la cuál contiene una sola vista del documento abierto. La ventana marco en una aplicación MDI, la cuál se deriva de CMDIFrameWnd, contiene una ventana hija especial llamada ventana MDICLIENT que ocupa y gestiona el área de trabajo de la ventana marco principal. Ésta a su vez, tiene ventanas hijas, las ventanas documento derivadas de CMDIChildWnd. La arquitectura de las ventanas marco se muestra en la figura B7. 113 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ CFrameWnd Ventana SDI del usuario CMDIChildWnd Ventana MDI del usuario CMDIFrameWnd Espacio de trabajo MDI Figura B7 Arquitectura para el soporte de ventanas marco. CMDIChildWnd: Esta clase proporciona la funcionalidad para las ventanas hijas de una aplicación MDI. CMDIFrameWnd: Esta clase proporciona el soporte para aplicaciones MDI. Clases para el soporte de vistas Una vista se asocia con un documento y actúa como interfaz entre el documento y el usuario. Una vista es una ventana en el diseño de una aplicación dentro del marco de trabajo de las MFC y se usa para presentar de manera gráfica el contenido del documento al usuario y de interpretar las operaciones del usuario sobre los datos del documento. La clase CView proporciona la funcionalidad para las clases vista definidas por el usuario. La figura B8 muestra la arquitectura de las clases vista. 114 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ CView CScrollView Vista del usuario CFormView Formulario del usuario Figura B8 Arquitectura de las clases vista. CView: Proporciona la funcionalidad básica para la visualización de los datos. CScrollView: Esta clase permite utilizar barras de desplazamiento automático. CFormView: Esta clase permite utilizar ventanas de diálogo como vistas lo que hace posible que la ventana principal de la aplicación tome el aspecto de una caja de diálogo. Clases para el soporte de ventanas de diálogo Los diálogos proporcionan la interfaz de usuario para gran parte de las funciones que requieren las aplicaciones de Windows. Los diálogos en la MFC comienzan con un objeto de la clase CDialog que encapsula la funcionalidad de las ventanas de diálogo definidas por el usuario y también de las predefinidas. La figura B9 muestra la arquitectura. CDialog CPropertyPage Diálogo del usuario Figura B9 Arquitectura de las clases diálogo. 115 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ CDialog: Esta clase encapsula todos los cuadros de diálogo. En la MFC todos los cuadros de diálogo son objetos que son instancias de la clase CDialog. Esta clase se deriva de la clase CWnd que le da funcionalidad de una ventana y de la clase CCmdTarget que le permite al diálogo tener su propio mapa de mensajes para manejar los mensajes. CPropertyPage: Esta clase encapsula las hojas de propiedades, que no son más que una colección de uno o más cuadros de diálogo y que permiten al usuario examinar o alterar las distintas propiedades asociadas con algún componente o subsistema de una aplicación. Clases para el soporte de controles Los controles son objetos gráficos que se dibujan sobre una ventana, tales como botones, cajas de texto, etiquetas, marcos, listas y barras de desplazamiento. En la siguiente figura B10 se muestran algunos de ellos. CButton CEdit CListBox CStatic Figura B10 Algunos controles. Clases para el soporte de gráficos. Existe un subconjunto de la API llamado Interfaz de Dispositivos Gráficos por sus siglas en inglés GDI el cuál es un programa ejecutable que procesa llamadas procedentes de una aplicación Windows y las pasa al manejador del dispositivo adecuado, para que éste ejecute las funciones específicas hardware que generan la salida [6]. Las funciones GDI son las que hacen posible que una aplicación de Windows se ejecute en diferente hardware. Las clases que componen esta interfaz se muestran en la figura B11. CObject Dibujo de gráficos Objetos de dibujo de gráficos Figura B11 Arquitectura para el soporte de gráficos. 116 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ Clases para el dibujo de gráficos Para dibujar un gráfico primero se crea un Contexto de Dispositivo (por sus siglas en inglés DC), sobre el que se quiere dibujar. Un Contexto de Dispositivo es una estructura que describe el entorno de visualización de una ventana, el dispositivo gráfico, sus atributos y los modos gráficos que afectan a la salida sobre el dispositivo. CDC CClientDC CPaintDC Figura B12 Arquitectura para el soporte del contexto de dispositivo. Objetos para el dibujo de gráficos Un objeto gráfico sirve como dispositivo para facilitar el trabajo de realizar un dibujo dentro de un Contexto de Dispositivo Gráfico que proporciona Windows, tales como: plumas, pinceles, mapas de bits, etc. La figura B13 muestra la jerarquía de clases. CGdiObject CBitmap CBrush CFont CPalette CPen Figura B13 Objetos de dibujo de gráficos. 117 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ Clases para el manejo de colecciones En la programación orientada a objetos, una colección es una clase capaz de contener y procesar grupos de objetos o de tipos estándar. Una colección se caracteriza por la forma en la que los objetos son organizados y almacenados y por los tipos de sus elementos. Las MFC proporcionan básicamente tres colecciones: arrays, listas y mapas o diccionarios. La figura B14 muestra algunas clases para el manejo de colecciones. CArray (template) Clist (template) CMap (template) CByteArray CPtrList CMapWordToPtr CObArray CObList CMapPtrToWord CPtrArray CStringList CMapPtrToPtr Figura B14 Arquitectura para el soporte de colecciones. Plantillas para colecciones Las clases para el manejo de plantillas de colecciones se pueden clasificar según su forma y diseño. La MFC ofrece clases para el manejo de tres tipos de forma de colección basadas en plantillas, las cuales se muestran en la figura B15. CTypedPtrArray CTypedPtrList CTypedPtrMap Figura B15 Clases para el soporte de plantillas de colecciones. Diagrama de clases de la MFC La figura B16 muestra la jerarquía de clases de la MFC con algunas de las clases más importantes. La MFC es un conjunto de clases que representan el marco de trabajo para simplificar el desarrollo de aplicaciones en ambiente Windows. 118 Anexo B: Jerarquía de clases de la MFC _____________________________________________________________________________________ CObject CCmdTarget CException CFile CWinThread CDocument CDocTemplate CGdiObject CWinApp CSingleDocTemplate CMultiDocTemplate CDC CWnd CClientDC CDialog CView CFrameWnd CPropertySheet CPropertyPage CScrollView CMDIChildWnd CMDIFrameWnd CPaintDC CControlBar Figura B16 Jerarquía de clases de la MFC. 119 Referencias bibliográficas Referencias bibliográficas [1] A. Martínez R., “Generador de Código para Lenguaje C, utilizando una Notación de Diseño Detallado”, Tesis de Maestría, Centro Nacional de Investigación y Desarrollo Tecnológico cenidet, 1997. [2] Bernd Bruegge, “Ingeniería de Software Orientado a Objetos”, Prentice Hall, 1ª. Edición, 2002. [3] Chuck Spar, “Aprenda Microsoft Visual C++ 6.0”, Mc Graw Hill, 1ª. Edición, 1999. [4] Craig Larman, “UML y Patrones”, Prentice Hall, 2ª. Edición, 2003. [5] Eric J. Braude, “Ingeniería de Software Una perspectiva orientada a objetos”, Alfaomega, 1ª. Edición, 2003. [6] F. Javier Ceballos, “Microsoft Visual C++”, Alfaomega Ra-Ma, 2ª. Edición, 2004. [7] Grady Booch, “Analisis y Diseño Orientado a Objetos con Aplicaciones”, Addison Wesley Longman, 2ª. Edición, 1996. [8] Grady Booch, “El Lenguaje Unificado de Modelados UML 2.0”, Addison Wesley, 2ª. Edición, 2006. [9] Herbert Schildt, “Programación con MFC 6.0”, Mc Graw Hill, 1ª. Edición, 1999. [10] Herbert Schildt, “Java 2”, Mc Graw Hill, 4ª. Edición, 2001. [11] Ian Sommerville, “Ingeniería de software”, Addison Wesley, 6ª. Edición, 2002. [12] I. A. Parra R., “ModeladoVisual Orientado a Objetos”, Tesis de Maestría, Centro Nacional de Investigación y Desarrollo Tecnológico cenidet, 2000. [13] Ivar Jacobson, “El Proceso Unificado de Desarrollo de Software”, Addison Wesley, 1ª. Edición, 2000. [14] James Rumbaugh, “Modelado y diseño orientados a objetos”, Prentice Hall, 3ª. Edición, 1999. [15] Jim Arlow, “Programación UML 2”, Anaya, 1ª. Edición, 2006. [16] Joseph Schumuller,“Aprendiendo UML en 24 Horas”, Prentice Hall, 1ª. Edición, 2000. 120 Referencias bibliográficas [17] Martín Folower, “UML Gota a Gota”, Addison Wesley, 1ª. Edición, 1999. [18] Paul Kimmel, “Manual de UML”, Mc Graw Hill, 1ª. Edición, 2007. [19] Presman S. Roger, “Ingeniería del Software un enfoque práctico”, Mc Graw Hill, 5ª. Edición, 2002. [20] S. Stelting, “Patrones de diseño aplicados a Java”, Prentice Hall, 1ª. Edición, 2003. [21] Rober C. Martin, “UML para Programadores Java”, Prentice Hall, 1ª. Edición, 2004. [22] R. Hernández S., “Metodología de la Investigación”, Mc Graw Hill, 3ª. Edición, 2003. [23] V. Aho Alfred, “Compiladores principio, técnicas y herramientas”, Addison Wesley Iberoamericana, 1ª. Edición, 1998. [24] BJ BJORK, RUSSELL C. ATM Simulation. Gordon College. Copyright 2004, http://www.math-cs.gordon.edu/courses/cs211/ATMExample/ Consultado el 22 de septiembre del 2008. [25] Gustavo Torossi, Modelado de Objetos con UML. http://www.chaco.gov.ar/UTN/disenodesistemas/apuntes/oo/ApunteUML.pdf, 9 Enero 2008 [26] Marc Gilbert G. Ingeniería del Software en Entornos http://www.uoc.edu/masters/oficials/img/917.pdf, 9 Enero 2008 [27] Eckel B. (2003). Thinking in Java (3.ª ed.). Upper Saddle River: Prentice Hall http://www.mindview.net/Books/TIJ/, 6 Enero 2008 [28] Grady Booch. (2003). El Lenguaje Unificado de http://elvex.ugr.es/decsai/java/pdf/3E-UML.pdf, 12 Octubre 2007 [29] Object Management Group. http://www.omg.org/, 3 Diciembre 2007 [30] Java Technology. http://java.sun.com. 18 Diciembre 2007 [31] Microsoft.NET. http://www.microsoft.com/net/, 26 Septiembre 2007 [32] Unified Modeling Language. http://www.uml.org/, 3 Octubre 2007 de SL Modelado 121 Referencias bibliográficas [33] Visual Studio 2005 Class Dessigner, http://blogs.msdn.com/classdesigner/, 1 Octubre 2007 ClassDesigner WebLog, http://blogs.msdn.com/classdesigner/ 1 Octubre 2007 [34] Free UML Class Designer, http://nclass.sourceforge.net/, 1 Noviembre 2007 [35] IBM, http://www.ibm.com/software/awdtools/developer/rose/, 2 Noviembre 2007 Wikipedia, http://en.wikipedia.org/wiki/Rational_Software, 2 Noviembre 2007 [36] MagicDraw, http://www.magicdraw.com/, 2 Noviembre 2007 [37] Plasticsoftware, http://plasticsoftware.com/, 3 Noviembre 2007 [38] University of Paderborn, Software Engineering Group, http://www.fujaba.de/, 3 Noviembre 2007 [39] Visual Paradigm, http://www.visual-paradigm.com/, 3 Noviembre 2007 [40] Gdpro Software from Advanced Software Technologies, http://wwwd0.final.com/computing/tools/gdpro/gdpro.htm, 4 Noviembre 2007 [41] Design Patterns, http://mit.ocw.universia.net/6.170/6.170/f01/pdf/lecture-12.pdf, 30 de enero de 2008 IngenieroSoftware, http://www.ingenierosoftware.com/analisisydiseno/patronesdiseno.php, 30 de enero de 2008 122 Capítulo 1 Introducción Capítulo 1 Introducción y antecedentes _______________________________________________________________ 1.1 Introducción Gran parte de los problemas que se presentan en el desarrollo del software, se debe al tiempo y a la falta de interpretación de las necesidades de los clientes. Cada vez se hace más evidente la necesidad de crear software de mayor calidad, lo que obliga al desarrollo de herramientas que permitan generar código a partir de un modelo, es decir, trabajar en un esquema de producir y desarrollar software justo a la medida y libre de defectos. Esto obliga a dichos desarrolladores a tener la suficiente habilidad para el análisis y el diseño del sistema y, así producir, cotizar y entregar productos en menos tiempo, para satisfacer las demandas de los clientes. El objetivo de la ingeniería de software va encaminado hacia el desarrollo de software y hacia la economía así como traducir las representaciones del software a una forma que pueda ser comprendida por la computadora. 1 Capítulo 1 Introducción El diseño de un sistema puede llevarse a cabo mediante el uso de los modelos. El uso de herramientas que permitan la construcción de modelos en los cuales se pueda efectuar visualmente el análisis, diseño y la generación de código como resultado del desarrollo del prototipo de manera visual, ahorraría el tiempo que se lleva en la codificación del software y, además, se tendría un sistema libre de defectos e inconsistencias, justo a la medida a partir de un modelo. El UML es una técnica de modelado de objetos y como tal supone la abstracción de un sistema para llegar a construirlo en términos concretos. El modelado no es más que la construcción de un modelo a partir de una especificación. Un modelo es una abstracción que se elabora para comprender algo antes de construirlo. El modelo omite detalles que no resultan esenciales para la comprensión y por lo tanto facilita dicha comprensión. Lo que en principio puede parecer complicado no lo es, ya que uno de los objetivos del UML es llegar a convertirse en la forma de definir modelos, no sólo es establecer una manera de modelar, sino que además, define un lenguaje con el que se puede abstraer cualquier tipo de modelo. Este trabajo de tesis propone la elaboración de una herramienta de software que permita generar código de clases en lenguaje Java a partir de un modelo, utilizando los diagramas de clases del UML y generar código en Java para el diseño detallado de los métodos de las clases a partir de los modelos con diagramas de Warnier. 1.2 Antecedentes El grupo de Ingeniería de Software del CENIDET (Centro Nacional de Investigación y Desarrollo Tecnológico) ha desarrollado una suite de modelado basado en UML, la cuál es conocida como MANGO. Éste trabajo tiene como antecedentes la definición e implementación de un Ambiente Integrado de Soporte para la Administración y Desarrollo de Sistemas de Software (AMASS) y el SCUML (SUITE CENIDET UML). El objetivo de MANGO es la construcción de una plataforma metodológica para la producción de sistemas de software de calidad, así como enfoque de reuso de componentes. Dicho ambiente toma como modelo de referencia, un ciclo de vida de software orientado a la construcción, integración, reutilización y mantenimiento de componentes de software. Dentro de MANGO se encuentran las herramientas SOODA (Sistema Orientado a Objetos para Diseño y Análisis) y DDVi (Diseño Detallado Visual), que son producto de las tesis: “Modelado visual orientado a objetos” [12] y “Generador de código para lenguaje C++, utilizando una notación de diseño detallado” [1] respectivamente. 2 Capítulo 1 Introducción SOODA es una herramienta que permite diseñar los diagramas de clases que corresponden a la estructura estática del sistema y sin duda el diagrama más importante dado que define los componentes esenciales del modelo. La herramienta DDVi en cooperación con SOODA permiten manejar un nivel más bajo de abstracción, el cuál ayuda a entender de manera gráfica el comportamiento de los métodos de una clase. El diseño detallado que se utiliza está basado en la notación de Warnier y está reforzado con un aspecto visual que tiene un mayor impacto en su comprensión y entendimiento. Otro beneficio importante es que la implementación de los métodos utilizando un diseño detallado nos coloca a un paso de su implementación. Finalmente, los algoritmos que hacen operar a los sistemas de software orientados a objetos, están dentro de los métodos y por tal razón hay que diseñarlos [12]. SOODA ofrece las siguientes ventajas: 1. Permite la elaboración de diagramas de clases que representan un aspecto de un modelo orientado a objetos. 2. Herramienta que automatiza dos aspectos esenciales en el diseño del software como son, el diseño de arquitectura y el diseño detallado de los métodos de clases, con una notación basada en diagramas de Warnier. 3. Herramienta que utiliza una interfaz visual para el modelado de sistemas orientados a objetos. 4. Provee documentación de la fase de diseño por medio de diagramas con información de tipo texto y de manera impresa. 5. Tiene la capacidad de producir el código de los algoritmos referentes a los métodos de una clase en lenguaje C++, sin modificar el aspecto visual de un diagrama de clases y todo dentro de la misma herramienta. Pero SOODA presenta las siguientes limitaciones: 1. No incluye la generación de código en lenguaje Java a partir del diseño detallado de los métodos. 2. No incluye la generación de código en lenguaje Java a partir de un modelo con diagramas de clases de UML. 3. Un aspecto importante del diseño de sistemas de software, es que el diseño es independiente del lenguaje en el que se codifique. Por tanto es importante, que la 3 Capítulo 1 Introducción herramienta pueda generar código no solamente en lenguaje C++ sino también en lenguaje Java. 4. Le faltan algunas mejoras en su ambiente de modelado, para facilitar el manejo de la herramienta en la creación del modelo visual de los sistemas, por ejemplo la funcionalidad del zoom, funciones de copiar/pegar, funciones de tamaños y tipos de fuentes. 5. Necesita de la herramienta DDVi para poder representar el diseño detallado de los métodos de clases. El trabajo de investigación que a continuación se presenta se propone a partir de las limitaciones y alcances de los trabajos futuros propuestos por el trabajo de tesis Modelado Visual Orientado a Objetos del Cenidet [12], ya que abre las posibilidades y las perspectivas para complementar y mejorar la herramienta. Es por ello que este nuevo proyecto tiene como objetivo principal, modelar sistemas orientados a objetos basado en la notación UML, con el fin de crear modelos visuales de manera rápida y sencilla, que permita generar código en lenguaje Java. Este trabajo se basa en las limitaciones de SOODA específicamente los puntos 1, 2 y 3 para de ahí partir y proponer el presente tema de tesis denominado “Generación Automática de Código Java a partir del Modelado Visual Orientado a Objetos”. 1.3 Planteamiento del problema El deseo de modelar un sistema, implica analizar y diseñar una situación real, basándose en un principio fundamental de abstracción para poder identificar las partes importantes de un sistema, con el fin de obtener con mayor claridad el funcionamiento, pero un sistema puede descomponerse en subsistemas y esta a su vez en otros subsistemas hasta concluir en partes más simples, con el fin de lograr mayor comprensión del problema. Los sistemas que están compuestos por varios subsistemas interconectados tienen un alto grado de complejidad en su construcción, lo que para un programador es más difícil su comprensión. Una solución a este problema son los modelos que permiten identificar con mayor claridad la arquitectura de un sistema, descubriendo los elementos importantes, discriminando a aquellos elementos que sean irrelevantes, identificando las relaciones entre ellos, logrando así disminuir el grado de complejidad. Los sistemas complejos se describen por lo general mediante más de un modelo, enfocándose cada uno en un aspecto diferente o nivel de precisión [2]. El problema consiste en que: los ambientes de modelado basados en UML no generan automáticamente el código del diseño detallado de los métodos, esto es la parte dinámica, lo que ocasiona que los desarrolladores deban codificarlos, implicando incremento en el tiempo de la elaboración. Existen herramientas CASE orientadas a objetos que permiten generar código a partir de los modelos creados, pero existen controversias ya que generalmente tales herramientas generan código fuente de manera incompleta. 4 Capítulo 1 Introducción SOODA es una herramienta CASE que permite especificar y capturar modelos orientados a objetos, solo genera código en lenguaje C++ a partir de los modelos con diagrama de clases utilizando ingeniería directa, además no es una herramienta que genere código de los métodos de las clases, necesita de otra herramienta como DDVi para generar código fuente también en C++ para dichos métodos. El problema que resuelve este proyecto de tesis es retomar la arquitectura de SOODA para generar código en lenguaje Java a partir de un modelo orientado a objetos con diagramas de clases del UML y el diseño detallado de los métodos de las clases con diagramas de Warnier. 1.4 1.5 Objetivos a) Desarrollar el generador de código en lenguaje Java, el cuál recupera el modelo que esta almacenado en una colección de datos y a partir de ahí pasar la información impresa en un archivo con formato texto. b) Generar código en lenguaje Java a partir de un modelo con UML en menos tiempo. c) Generar código en Java más completo, que se aproxime al nivel de abstracción del diseño de un modelo orientado a objetos. d) Generar código en Java a partir de los diagramas de clases con UML y diagramas de Warnier, y que esté libre de errores e inconsistencias. Estado del arte Desde comienzos de la década de los 80, el paradigma “orientado a objetos” ha ido madurando como un enfoque de desarrollo de software alternativo a la programación estructurada o modular. Se comenzaron a crear diseños de aplicaciones de todo tipo usando una forma de pensar orientada a objetos y a implementar estos diseños utilizando lenguajes orientados a objetos. Sin embargo, el análisis de requisitos quedo atrás. No se desarrollaron técnicas de análisis específicamente orientadas a objetos. El Análisis Orientado a Objetos (AOO) se basa en conceptos sencillos, conocidos desde la infancia y que aplicamos continuamente: objetos y atributos, el todo y las partes, clases y miembros. Puede parecer llamativo que se haya tardado tanto tiempo en aplicar estos conceptos al desarrollo de software. Posiblemente una de las razones es el éxito de los métodos de análisis estructurados, basados en el concepto de flujo de información, que monopolizaron el análisis de sistemas de software durante los últimos veinte años. 5 Capítulo 1 Introducción En cualquier caso, el paradigma orientado a objetos ha sufrido una evolución similar al paradigma de programación estructurada: primero se utilizaron los lenguajes de programación estructurados, los que permiten la descomposición modular de los programas, esto condujo a la adopción de técnicas de diseño estructuradas y de ahí se dio paso al análisis estructurado. El paradigma orientado a objetos ha seguido el mismo camino: el uso de la Programación Orientada a Objetos (POO) ha modificado las técnicas de diseño para adaptarlas a los nuevos lenguajes y ahora se están empezando a utilizar técnicas de análisis basadas en esta nueva forma de desarrollo de software. El AOO ofrece un enfoque nuevo para el análisis de requisitos de sistemas de software. En lugar de considerar el software desde una perspectiva clásica de entrada/proceso/salida, como los métodos estructurados clásicos, se basa en modelar el sistema mediante los objetos que forman parte de él y las relaciones estáticas (herencia y composición) o dinámicas (uso) entre estos objetos. Este enfoque pretende conseguir modelos que se ajusten mejor al problema real, a partir del conocimiento del llamado dominio del problema. Este intento de conocer el dominio del problema ha sido siempre importante; no tiene sentido empezar a escribir los requisitos funcionales de un sistema y menos aún diseñarlo o programarlo sin estudiar primero cual es el problema o qué se espera de un sistema. La ventaja del AOO es que se basa en la utilización de objetos como abstracciones del mundo real. Esto nos permite centrarnos en los aspectos significativos del dominio del problema (en las características de los objetos y las relaciones que se establecen entre ellos) y este conocimiento se convierte en la parte fundamental del análisis del sistema de software, que será luego utilizado en el diseño y la implementación. El uso del AOO puede facilitar mucho la creación de prototipos y técnicas de desarrollo evolutivo de software. Los objetos son inherentemente reutilizables y se puede crear un catálogo de objetos que podemos usar en sucesivas aplicaciones. De esta forma, podemos obtener rápidamente un prototipo del sistema, que pueda ser evaluado por él cliente, a partir de objetos analizados, diseñados e implementados en aplicaciones anteriores. Y lo que es más importante, dada la facilidad de reutilización de estos objetos, el prototipo puede ir evolucionando hasta convertirse en el sistema final, según vamos refinando los objetos de acuerdo a un proceso de especificación incremental. La orientación a objetos ofrece un índice para nuestro conocimiento sin importar que quede expresado en función de reglas, lógica, funciones, lenguajes relacionales, redes neuronales o cualquier otra cosa. Lo que es más, si ampliamos esta idea, se puede emplear la OO como un procedimiento para organizar e interconectar muchas tecnologías de software diferentes, incluyendo bases de conocimiento, computación paralela, reingeniería de los negocios y desarrollo rápido de aplicaciones. La orientación a objetos se puede utilizar como un mecanismo que organice e interconecte muchos tipos distintos de procedimientos de sistemas. 6 Capítulo 1 Introducción Herramientas para el desarrollo de objetos. Las herramientas de desarrollo de software tradicionales sólo incorporan conocimiento sobre el código fuente, pero ya que el análisis y diseño orientados a objetos ponen el énfasis en abstracciones y mecanismos clave, se necesitan herramientas que puedan concentrarse en semánticas más ricas. Además, el rápido desarrollo de versiones definido por el macroproceso del desarrollo orientado a objetos requiere de herramientas que ofrezcan una rápida alternancia, especialmente para el ciclo de edición, compilación, ejecución y depuración. Algunas herramientas analizadas fueron las siguientes: Class Designer [33] Esta herramienta viene integrada con Visual Studio 2005 y permite crear los diagramas de clases y generar código a partir de las clases, los diagramas y el código están sincronizados ya que cualquier cambio en los diagramas se ve reflejado en el código generado. Características: Soporta OMG UML 1.1 Genera código fuente en lenguajes de programación como Visual Basic y Visual C#. Ingeniería directa e inversa para código en Visual Basic y Visual C#. Generación personalizable de código. Incluye modelos prefabricados de librerías de clases populares. Apoya vínculos OLE para sus diagramas. Doble byte habilitado para soportar lenguajes internacionales. Búsqueda gráfica de Interfaces, clases y relaciones. El usuario puede modificar colores y fuentes. Capacidad para exportar sus modelos a Object Team. Agregación de comentarios Class Designer permite crear y visualizar la estructura de las clases y las relaciones con otros elementos del modelo. Permite crear múltiples vistas y cada vista puede personalizarse para destacar un aspecto diferente de su diseño. Por ejemplo, en un diagrama puede mostrar la vista detallada de una clase con todos sus atributos y operaciones, en otro diagrama se pueden suprimir estos detalles y mostrar sus asociaciones con otras clases. Permite simplificar y personalizar la presentación de su modelo según sus preferencias. Los generadores de código integrados de Visual C# y Visual Basic le ayudan a instrumentar sus sistemas más rápidamente. Se puede generar en ambos lenguajes desde el mismo modelo, permitiendo así la creación de sistemas particionados que usan una sola herramienta. La generación de código puede personalizarse al indicar por ejemplo, el orden en que se escriben las clases. Permite el control completo sobre el orden en que las clases se 7 Capítulo 1 Introducción generan en un archivo, así también el orden de los atributos y operaciones dentro de una clase. El generador de código puede instrumentar automáticamente asociaciones entre clases, permitiéndole concentrarse en su diseño lógico. Class Designer viene con parsers integrados que son rápidos y fáciles de usar. Con Class Designer se puede aplicar ingeniería inversa rápidamente del código existente. Los parsers trabajan de acuerdo con otros generadores de código como el ClassWizard de Visual C++, permitiendo manipular el código con cualquiera de las dos herramientas. Los cambios directos en el código pueden sincronizarse con el modelo en cuestión de minutos. Uno de los beneficios más grandes e inmediatos que se obtiene al utilizar Class Designer es visualizar y reutilizar código existente. Esa es la razón por la que incluye los siguientes modelos para ayudar a ahorrar tiempo en el desarrollo de software: Biblioteca estándar C++ (incluyendo STL). Clases Base de Microsoft (MFC). Biblioteca de Plantillas de Microsoft Active X(ATL). Modelo de Objetos Componente de Microsoft (COM). Kit de Desarrollo de Java (JDK), incluyendo Java Beans. Sin embargo, con todas estas ventajas que ofrece Class Designer, no permite la generación del código detallado de los métodos a partir del modelo orientado a objetos. NClass [34] NClass versión 1.0 es una herramienta que utiliza los diagramas de clase de UML, genera código en C# y Java a partir del modelo y también utiliza ingeniería inversa para generar el modelo a partir del código fuente. La interfaz de usuario es muy simple y amigable lo que agiliza en gran medida el desarrollo de las aplicaciones. Las características más importantes de esta herramienta son: Genera código en lenguaje Java y C#. Permite la declaración y tipos de acceso de los miembros de la clase. Contiene verificación sintáctica y semántica. Crea un archivo texto del código fuente generado. Permite la configuración de estilos de diagramas. Permite imprimir y guardar la imagen del modelo. Utiliza notación de UML. Utiliza ingeniería directa e inversa. Esta herramienta no permite aún el manejo de múltiples proyectos y esquemas al mismo tiempo, tampoco la multiplicidad de roles y relaciones, aunque en la versión 2.0 se espera que tenga esta funcionalidad. Esta herramienta tampoco permite la generación del código detallado de los métodos a partir del modelo orientado a objetos. 8 Capítulo 1 Introducción IBM Rational Rose [35] El Object Management Group (OMG), aceptó el proyecto de Rational de lanzar a UML como estándar oficial de notación para el desarrollo de software bajo el esquema orientado a objetos. Rational fue la empresa que promovió la iniciativa y con ello confirma el liderazgo que posee dentro de este campo. Características: Capacidad de reingeniería de software para integrar sistemas existentes. Capacidad de mezclar múltiples lenguajes dentro de un mismo modelo. Ingeniería inversa sobre los componentes COM, ActiveX y Java. Perfeccionamiento en generación de código para el desarrollo de interfaces. Integración con herramientas de administración de la configuración. Automatización de funciones. Integración con herramientas de prueba. Integración con herramientas de Administración de Requerimientos. Notación UML 2.0. Librería de Frameworks. Rose permite desarrollar sus componentes y las interfaces de manera más efectiva mediante el modelado de componentes. Se puede aplicar ingeniería inversa a los componentes de un diseño, para explorar sus interfaces e interrelaciones de otros componentes en el modelo basta con sólo arrastrar y bajar componentes desde un sistema de archivos en el diagrama de componentes. Esto le permite realizar ingeniería inversa, adaptar, adquirir y crear componentes para su sistema en forma rápida y eficiente. Mediante el modelo visual se pueden crear componentes (modelos), que al salvarlos pueden ser compartidos y reutilizados por varios proyectos, permitiendo que los cambios sean fácilmente incorporados a los proyectos existentes En Rose 2000 edición Enterprise, tiene soporte de multilenguaje, permitiendo construir modelos para lenguajes mezclados. Genera código en Java, C++, Ada, Smalltalk, así también en lenguajes RAD (Rapid Application Development) tales como: Visual Basic, PowerBuilder y Forté, también genera código en Lenguaje de Definición de Interfaz (IDL) para aplicaciones CORBA y en Lenguaje de Descripción de Datos (DDL) para aplicaciones de base de datos. Rose permite moverse fácilmente del análisis al diseño, a la implementación y regresar al análisis nuevamente y así apoyar todas las etapas del ciclo de vida de un proyecto. Rose soporta un proceso de administración dinámica de cambios con ingeniería directa, inversa, características de actualización de modelos que le permiten alterar su instrumentación, evaluar sus cambios y automáticamente incorporarlos en su diseño. El soporte de una ingeniería bidireccional asegura que el ciclo iterativo de desarrollo es controlado y productivo. Es 9 Capítulo 1 Introducción pertinente aclarar que el nuevo nombre de IBM Rational Rose se debe a que Rational fue comprada por la empresa IBM. Sin embargo, con todas estas ventajas que ofrece IBM Rational Rose, no permite la generación de código a nivel detallado de los métodos a partir de un modelo orientado a objetos. MagicDraw [36] MagicDraw versión 15.1 es una herramienta CASE de modelado visual desarrollada en Java que usa la notación UML. La herramienta facilita el análisis y el diseño de los sistemas orientados a objetos y bases de datos. MagicDraw provee los mecanismos de ingeniería directa para generar código en Java, C++, C#, CORBA IDL y WSDL así como ingeniería inversa para crear el modelo a partir de los lenguajes antes mencionados. MagicDraw también proporciona el mecanismo para modelar esquemas de base de datos y la generación de DDL. MagicDraw es un editor práctico del UML, también contiene las funciones para cortar, copiar y pegar. Se apoya en la especificación de UML 2.0. Como se mencionó anteriormente esta herramienta permite la generación de código fuente a partir del modelo, también permite de manera manual en su IDE escribir más código a mano, también permite generar el modelo a partir del código fuente y en su interfaz puede manejar múltiples vistas. Se pueden generar informes en html para cada elemento modelo. MagicDraw permite seleccionar qué partes del modelo se van a incluir en el informe y el estilo del formato. MagicDraw es una herramienta que puede generar diagramas de dependencia, recupera y dibuja árboles de herencia, y permite cualquier otra clase de relación tal como dependencias, asociaciones, realizaciones y uso de la clase. MagicDraw puede generar las partes del modelo automáticamente, se puede seleccionar cualquier objeto y generar las clases necesarias para hacer que se adapte con un patrón del diseño. Características: Capacidad de ingeniería directa e inversa. Capacidad de mezclar múltiples proyectos. Generación de código en Java, C++ y Corba. Notación UML 2.0. Integración con herramientas de administración de la configuración, soporta Rational Rose. Automatización de funciones. 10 Capítulo 1 Introducción Integración con herramientas de pruebas. Guía de Interfaz de Usuario en Inglés, Alemán, Japonés y Thai. La herramienta contempla una amplia variedad de sistemas, incluyendo diseño en tiempo real, cliente – servidor y distribuido. MagicDraw funciona en diferentes sistemas operativos, tales como Windows 98/NT/2000/XP/Vista, Solaris, OS/2, Linux, Hp-ux-ux, AIX, MacOS (x), se apoya Java 2. Sin embargo, con todas estas ventajas que ofrece MagicDraw, no permite la generación de código a nivel detallado de los métodos a partir de un modelo orientado a objetos. Plastic [37] Plastic versión 2.0 es una herramienta que utiliza los diagramas de clase de UML, ofrece un diseño simple y atractivo para los usuarios, genera código en html y en lenguaje Java a partir del modelo, también utiliza ingeniería inversa para generar el modelo a partir del código fuente. La interfaz de usuario es muy simple y amigable lo que simplifica el manejo de las operaciones mas utilizadas. Las características más importantes de esta herramienta son: Genera código en lenguaje Java y html. Permite la declaración y tipos de acceso de los miembros de la clase. Tiene funciones para hacer zooms, cortar, copiar y pegar. Crea un archivo texto del código fuente generado. Permite imprimir y guardar la imagen del modelo. Utiliza notación de UML. Utiliza ingeniería directa e inversa. Esta herramienta no tiene aún en su interfaz el manejo de diversas vistas y esquemas al mismo tiempo, tampoco la integración con otras herramientas de desarrollo de entorno visual, aunque en la versión 2.0 se espera que tenga esta funcionalidad. Esta herramienta tampoco permite la generación del código detallado de los métodos a partir del modelo orientado a objetos. Fujaba [38] Fujaba Tool Suite versión 5.0 es una herramienta CASE desarrollada en Java, que usa los diagramas de clase y los diagramas de actividades de UML, ofrece un diseño simple y atractivo para los usuarios, genera código en lenguaje Java y permite compilar el código produciendo un ejecutable. El Fujaba Tool Suite RE Edition está especialmente configurado con plugins para ingeniería inversa y reconocimiento de patrones de diseño. La interfaz de 11 Capítulo 1 Introducción usuario es muy simple y amigable lo que simplifica el manejo de las operaciones mas utilizadas. Las características más importantes de esta herramienta son: Genera código en lenguaje Java. Permite la declaración y tipos de acceso de los miembros de la clase. Tiene funciones para guardar, salvar e imprimir el código. Tiene funciones para cortar, copiar, pegar, reemplazar y encontrar en el editor de código de Fujaba. Crea un archivo texto del código fuente generado. Permite imprimir y guardar el proyecto creado. Utiliza notación de UML. Utiliza ingeniería directa e inversa. Esta herramienta no tiene aún en su interfaz el manejo de diversas vistas y esquemas al mismo tiempo, tampoco la integración con otras herramientas de desarrollo de entorno visual, aunque en la versión 5.0 se espera que tenga esta funcionalidad. Esta herramienta tampoco permite la generación del código detallado de los métodos a partir del modelo orientado a objetos. Visual Paradigm [39] Visual Paradigm Suite 3.2 es una poderosa herramienta CASE que usa UML y se integra con JBuilder y Eclipse, ofrece el servicio de importación con Rational Rose, XMI y XML, bajo la plataforma en Java corre en ambiente Windows y Linux. Visual Paradigm contiene los mecanismos de ingeniería directa para generar código en Java, Visual C++, VB.NET, C#, PHP, Delphi, Perl, Ada95, Python, Ruby, ActionScript, XML Schema, Objective-C, ODL, así como el mecanismo de ingeniería inversa para que a partir del código fuente en los lenguajes antes mencionados genere el modelo. Visual Paradigm cubre todos los aspectos para la creación de documentación de los proyectos en UML, generando los reportes de la documentación en archivos PDF y html, además permite la importación y exportación de los proyectos de Visual Paradigm. Las características más importantes de esta herramienta son: Genera código en diferentes lenguajes incluyendo a Java. Permite la declaración y tipos de acceso de los miembros de la clase. Tiene funciones para guardar, salvar e imprimir el código. 12 Capítulo 1 Introducción Tiene funciones para cortar, copiar, pegar, y reemplazar. Crea un archivo texto del código fuente generado. Permite imprimir y guardar el proyecto creado. Utiliza notación de UML. Utiliza ingeniería directa e inversa para diferentes lenguajes. Facilita el cambio de las propiedades de los componentes. Facilidad en el enlace de los componentes. Visual Paradigm no solo es una herramienta CASE de modelado visual para UML, ya que contiene otras herramientas para el manejo del mapeo de objetos relacionales los cuales están apoyados con las versiones Enterprise Edition de Visual Paradigm y Professional Edition de Visual Paradigm para UML, además contiene la integración con otras herramientas de desarrollo de entorno visual. Con todas las ventajas antes mencionadas, esta herramienta tampoco permite la generación del código detallado de los métodos a partir del modelo orientado a objetos. Gdpro [40] Maneja dos notaciones UML y OMT, realiza generación de código en C++ y Java, permite la ejecución de ingeniería inversa con lo cual los diagramas y el código permanecen sincronizados, soporte multiusuarios, cualquier número de usuarios pueden trabajar concurrentemente, acceso compartido a modelos y objetos, bloqueo a nivel de objetos y modelos. Permite adaptar la notación utilizada, al crear símbolos, atributos, relaciones para formar un nuevo modelo. Genera documentos en formatos HTML y ASCII. Los usuarios pueden trabajar en plataformas heterogéneas y redes diferentes. Diseño de colaboración en tiempo real, al habilitar a todos los usuarios para que puedan ver los cambios inmediatamente. Los equipos de trabajo pueden colaborar a través de internet, LANs o WANs. Genera reportes del modelo de objetos, dinámico, funcional y otros definibles por el usuario. Posee tutoriales de ayuda para el aprendizaje de los métodos de modelado. Las características más importantes de esta herramienta son: Genera código fuente a partir del diagrama de clases. Soporte para el desarrollo y colaboración de múltiples usuarios Tiene funciones para guardar, salvar e imprimir el código. Tiene funciones para cortar, copiar, pegar, y reemplazar. Crea un archivo texto del código fuente generado. Permite imprimir y guardar el proyecto creado. Utiliza notación de UML. Utiliza ingeniería directa e inversa. Soporta la reusabilidad de componentes de software. Funciona con los sistemas operativos Windows NT/95/98 y Solaris. 13 Capítulo 1 Introducción La herramienta Gdpro posee muchas características importantes y de mucha utilidad, sin embargo esta herramienta no permite realizar el diseño de los métodos de una clase con una notación visual estructurada de diseño detallado. SOODA Y DDVI [12] SOODA es una herramienta de ingeniería de software asistida por computadora, es decir, es un programa que ayuda a un ingeniero de software a especificar y diseñar un sistema, utilizando parte de un lenguaje específico de modelado, que se basa en la tecnología de objetos. La etapa de apoyo en la que se ubica es el diseño de software con un perfil orientado a objetos, por lo tanto es una herramienta de especificaciones de diseño y generadora de código. SOODA tiene la función principal de ayudar a la elaboración de diagramas de clases utilizando la notación UML, de tal forma que permite al usuario, modelar los diagramas de clases por medio de un editor de manera visual con la ayuda del mouse y teclado. DDVi es un sistema de software cuyo objetivo es ayudar en la elaboración de diagramas de diseño detallado, utilizando una notación basada en diagramas de Warnier, ofrece al usuario plantear sus diseños detallados de una manera gráfica haciendo uso del ratón y el teclado. Esta herramienta también genera código en C++ referido al diagrama y permite guardar y recuperar los diagramas elaborados. SOODA y DDVi son dos programas que se ejecutan por separado y comparten información para lograr un fin común. Por una parte, mediante la herramienta SOODA se elabora un diagrama de clases y por otro lado DDVi sirve para elaborar los diseños detallados de los métodos de las clases que forman un diagrama de clases. Posteriormente el código generado en C++, por ambas herramientas se combinan para ofrecer en archivos con formato texto y con extensiones .cpp y .h la declaración de clases y la definición de sus métodos. La herramienta SOODA posee algunas características importantes y de mucha utilidad, sin embargo esta herramienta no permite realizar el diseño de los métodos de una clase, con una notación visual estructurada de diseño detallado, para ello necesita de la herramienta DDVi que le sirve para complementar el diseño detallado de los métodos, además no maneja toda la funcionalidad de UML y sólo genera código en C++. La tabla 1.1 compara algunas características importantes de las herramientas CASE de modelado Orientado a Objetos analizadas y probadas. 14 Capítulo 1 Introducción Características Ambientes Permite la generación de código a nivel de diseño detallado de los métodos Permite la generación de código en lenguaje Java a partir del modelo visual. Permite utilizar la notación UML para la presentación visual del modelo NO SI SI NO SI SI, aunque sólo diagramas de clases NO SI NO SI SI, aunque sólo los diagramas de clases y actividades NO SI SI NO SI SI NO SI SI Rational Rose 2002 NClass 1.0 Plastic 2.0 Fujaba Tool Suite 5 SI, aunque sólo diagramas de clases MagicDraw 15.1 Class Designer Visual Suite 3.2 Paradigm Gdpro 5.1 SOODA NO SI SI, al conectarse a DDVi NO, solo genera código en lenguaje C++ SI, aunque maneja ciertas adaptaciones a los diagramas SI, aunque sólo los diagramas de clases Permite generar código fuente en Java a partir del modelo en UML. SI, pero sin el diseño detallado de los métodos SI, pero sin el diseño detallado de los métodos SI, pero sin el diseño detallado de los métodos SI, pero sin el diseño detallado de los métodos SI, pero sin el diseño detallado de los métodos SI, pero sin el diseño detallado de los métodos SI, pero sin el diseño detallado de los métodos SI, pero sin el diseño detallado de los métodos NO, y sin el diseño detallado de los métodos Tabla 1.1 Herramientas CASE que generan código a partir del modelo orientado a objetos. 15 Capítulo 1 Introducción 1.6 Propósito del proyecto Diseñar y desarrollar una herramienta de ingeniería directa de software utilizando ingeniería directa, que permita generar código en lenguaje Java a partir de un modelo de diseño con diagramas de clases de la notación UML y el diseño detallado de los métodos de clases con diagramas de Warnier, esto ayudará a generar código en Java libre de errores de sintaxis permitiendo mejorar la productividad en el desarrollo de software. Los objetivos específicos que se deben cubrir son: Diseñar y desarrollar una herramienta bajo la arquitectura de SOODA, que permita generar código en lenguaje Java. Implementar en la herramienta DDVi, la funcionalidad del diseño detallado de los métodos de una clase para generar código en Java utilizando los diagramas de Warnier. Mostrar de manera con archivos en formato texto la generación del código en Java a partir del modelo obtenido. Que colaboren más áreas de investigación sobre los lenguajes de cuarta generación, para futuras investigaciones en el desarrollo de estas herramientas. 1.7 Justificación En los últimos años se ha trabajado en el área de desarrollo de sistemas para encontrar técnicas que permitan incrementar la productividad y el control de la calidad en cualquier proceso de elaboración de software, y hoy en día la tecnología CASE (Computer Aided Software Engineering) reemplaza al papel y al lápiz por la computadora para transformar la actividad de desarrollar software en un proceso automatizado, la nueva generación de herramientas CASE permiten al ingeniero de software modelar gráficamente una aplicación de ingeniería y después generar el código fuente a partir del modelo gráfico [19]. Aunque las herramientas CASE que se ofrecen hoy en día no producen un código fuente eficiente y, que el mantenimiento de grandes sistemas de software desarrollados mediante los generadores de código es cuestionable, siguen teniendo una gran aceptación. Los diagramas de clases muestran las diferentes clases que componen un sistema y cómo se relacionan unas con otras. Se dice que los diagramas de clases son diagramas “estáticos” porque muestran las clases, junto con sus métodos y atributos, así como las relaciones estáticas entre ellas: qué clases “conocen” a qué otras clases o qué clases “son parte” de otras clases, pero no muestran la funcionalidad de los métodos mediante los que se invocan entre ellas, esto es así porque el objetivo no es el diseño detallado de los métodos sino mostrar las clases que forman la arquitectura del sistema. 16 Capítulo 1 Introducción En el caso de SOODA genera código fuente de las estructuras de clases en lenguaje Visual C++, pero no el diseño detallado de los métodos de una clase, para ello necesita de la herramienta DDVi. Las principales razones que justifican el desarrollo de este proyecto son: Complementar dos procesos que son parte importante del modelo de desarrollo de software, el cuál es el diseño de la arquitectura por medio del diagrama de clases y el diseño detallado de los métodos por medio de diagramas de Warnier. A veces el código que se genera no se aproxima al nivel de abstracción del modelo. Es necesario crear una herramienta CASE que permita generar código derivado del modelo. Se invierte más tiempo en la codificación que en el análisis y diseño del software. Por ello es necesario crear una herramienta CASE que permita crear el modelo y a partir de ahí generar de manera automática el código. Cuando se hace la codificación manual se generan errores de sintaxis, por lo que es necesario automatizar la generación del código. 1.8 Beneficios Con esta herramienta se persigue mejorar el desarrollo del software, con lo que se obtendrán los siguientes beneficios: 1. Complementar la funcionalidad de SOODA al permitir la inclusión de generación de código en lenguaje Java a partir de un modelo con notación UML con diagramas de clases. 2. Integrar la fase de desarrollo del diseño detallado de los métodos de las clases, con la generación del código en Java. 3. Reducir el tiempo de desarrollo de software. 4. Generar código en lenguaje Java libre de errores; en la arquitectura del modelo y el diseño detallado de los métodos de las clases. 1.9 Alcances y limitaciones del proyecto La herramienta a desarrollar para el modelado visual orientado a objetos y la generación automática de código en Java, tendrá los siguientes alcances y limitaciones. 17 Capítulo 1 Introducción 1. Crear un ambiente visual que permita diseñar modelos, por medio de diagramas de clases bajo la notación UML y a partir de ahí generar código en lenguaje Java. 2. Generar código en lenguaje Java para el diseño detallado de los métodos de las clases, utilizando diagramas de Warnier. 3. Aunque los resultados de esta tesis podrán ser usados para generar código en lenguaje Java a partir de un modelo con diagrama de clases y un modelo para el diseño detallado de los métodos con diagramas de Warnier, no se considera la generación de clases abstractas e interfaces, paquetes, así como la generación de métodos abstractos, ya que se deja abierto para futuras investigaciones. 1.10 Organización de la tesis En el capítulo 1 se exponen los antecedentes y la problemática que existe en el desarrollo de software. Se describen las características de las herramientas de generación de código. Se describen las características de la herramienta SOODA, su relación con el Modelo Orientado a Objetos y con UML. En el capítulo 2 se presentan los conceptos teóricos sobre la programación orientada a objetos. Un panorama general sobre la programación en ambiente Windows con el uso de las MFC. Se describen las características de Lenguaje Unificado de Modelado UML, los diagramas de clases y su relación con la programación orientada a objetos. Finalmente se da un panorama sobre el diseño detallado de los métodos. En el capítulo 3 se presenta el proceso como guía para generar código en lenguaje Java a partir de un modelo con diagramas de clases de UML. También se presenta el proceso para la generación de código en Java, de los métodos de una clase con la herramienta DDVi, además se explican los elementos que forman parte de la herramientas SOODA para generar código en lenguaje Java a nivel de clases, así como los elementos que forman parte del diseño detallado de los métodos de las clases y así representar la información del modelo en un archivo de texto plano. En el capítulo 4 se presentan casos de pruebas con ejemplos de programas en lenguaje Java generados a partir de un modelo y del código fuente de un sistema de un cajero automático con diagramas de clases del UML [24] utilizando la herramienta SOODA, por último la utilización de la herramienta DDVi para generar código en Java para el diseño detallado de los métodos de una clase. En el capítulo 5 se muestran las conclusiones, se analizan los principales resultados y aportaciones de la tesis, las áreas de aplicación y las tendencias que podrían ser abordados en el futuro para extender esta herramienta. 18 Capítulo 2 Marco Teórico Capítulo 2 Marco teórico ____________________________________________________________ A continuación se presentan algunos antecedentes, definiciones, herramientas y conceptos teóricos básicos utilizados, los que sirven como marco de referencia para el desarrollo de este trabajo. 2.1 Lenguajes de programación La finalidad de los lenguajes de programación es facilitar a los seres humanos la comprensión, la escritura y la modificación de los programas. El objetivo primordial de un programa expresado en un lenguaje de computación no es ser ejecutado directamente por una computadora, sino comunicar de manera comprensible para un ser humano lo que una computadora debe hacer para resolver un determinado problema. Los lenguajes de programación facilitan en gran medida la solución de un problema de manera cómoda para el que escribe el programa, pero que sirve para comunicar a la computadora el proceso para 19 Capítulo 2 Marco Teórico llegar a la solución. Dado que las personas tienen serias dificultades para leer, escribir y modificar programas en lenguaje de máquina se inventaron los lenguajes de programación. Si el programador escribe código desordenado esto provoca que dicho código sea difícil de leer y se pierde el interés al no comprender lo que el código intenta hacer, además, es importante que los programadores sean capaces de comprender el código de manera rápida para poder encontrar los errores de programación y dar mantenimiento, reparando las inconsistencias y defectos que existan de manera oportuna. El código fuente es una forma de comunicación y así como a alguien podría no querer leer un texto con errores ortográficos y mala puntuación, los programadores deben intentar escribir buen código libre de errores, de tal forma que sea fácil de entender y ser modificado por otros. 2.2 Importancia del modelado “Un modelo es una simplificación de la realidad y es esencial en el desarrollo de software” [27] para: Comunicar la estructura de un sistema complejo Especificar el comportamiento deseado del sistema Comprender mejor lo que estamos construyendo Descubrir oportunidades de simplificación y reutilización Los modelos además, al no ser una representación que incluya todos los detalles de los originales, permiten probar más fácilmente los sistemas que modelan y permiten localizar más fácilmente los errores. Los modelos permiten mejorar la comunicación con el cliente por distintas razones: Es posible enseñar al cliente una posible aproximación de lo que será el producto final. Proporcionan una primera aproximación al problema, ya que permite visualizar cómo quedará el resultado. Reducen la complejidad en subconjuntos los que son fácilmente tratables por separado. 2.3 Desarrollo basado en componentes La ingeniería de software basada en componentes surgió a finales de los 90’s como un enfoque basado en la reusabilidad para el desarrollo de sistemas de software, el motivo fue la frustración de que el desarrollo orientado a objetos no permite la reusabilidad extensiva, las clases de objetos están muy ligadas a la aplicación. Los componentes son más abstractos que las clases de objetos por lo que se consideran más independientes en el momento de usarlas [11]. Cuando una aplicación solicita un servicio, llama a un componente sin importar la tecnología en que fue desarrollado. Básicamente un componente tiene dos características: 20 Capítulo 2 Marco Teórico 1. Es una entidad ejecutable e independiente. 2. Publican su interfaz y todas sus interacciones son a través de ella. Un componente es una clase o conjunto de clases cuya característica principal es la reusabilidad. Una clase que no puede utilizarse sino en presencia de otro conjunto de clases, esto no es un componente. 2.4 Patrones en la ingeniería de software Los patrones de diseño son soluciones documentadas, las cuales son probadas por expertos y que las aplican para dar solución a nuevos problemas, estas soluciones son parte de la experiencia que los programadores han tenido y que ha funcionado con éxito. Por tanto, cuando se encuentran con problemas similares es posible incrustar dicha solución para resolver el problema. Esto beneficia en gran medida al diseño de software orientado a objetos, pues el empleo de patrones ayuda al logro de crear buenos diseños. Con el paso del tiempo al estar creando diseños de software se va adquiriendo experiencia en el desarrollo de aplicaciones, donde generalmente se observa que hay ciertos patrones que se repiten para dar solución a problemas semejantes, lo ideal sería entonces crear una biblioteca de patrones y reusarlos para crear soluciones óptimas. Estos patrones facilitan la creación de objetos en los sistemas orientados a objetos [41]. En la tabla 2.1 se presentan algunos patrones de diseño orientados a objetos. Tipo de patrón Patrones de creación Patrones estructurales Patrones de comportamiento Nombre del patrón Abstract factory Builder Factory method Prototype Singleton Adapter Bridge Composite Decorador Facade Flyweight Proxy Chain of responsability Command Interpreter Iterator Mediator Memento Observer 21 Capítulo 2 Marco Teórico State Strategy Template method Visitor Tabla 2.1 Patrones de diseño orientados a objetos. Patrones de creación: estos patrones facilitan la creación de objetos en un sistema [20]. La mayoría de los sistemas orientados a objetos, necesitan crear instancias de muchas clases y estos patrones facilitan el proceso de creación ayudando a proporcionar las siguientes capacidades: Instanciación genérica: permite crear objetos en un sistema sin tener que identificar una clase específica en el código. Simplicidad: algunos de los patrones facilitan la creación de objetos, por lo que los invocadores no tendrán que escribir grandes y complejos códigos para crear un objeto. Restricciones de creación: algunos patrones forzan restricciones en el tipo o el número de objetos que pueden ser creados en el sistema. Patrones estructurales: los patrones estructurales describen formas efectivas de particionar y combinar los elementos de una aplicación. Estos tipos de patrones permiten la comunicación entre sistemas incompatibles, también permiten presentar una interfaz más simple al usuario. Patrones de comportamiento: estos patrones están relacionados con el flujo de control en un sistema. Ciertas formas de organizar el control en un sistema pueden generar beneficios en la eficiencia y mantenimiento de un sistema. La herramienta SOODA esta construida con algunos patrones de diseño, tal es el caso de la estructura documento/vista donde se aplica un patrón estructural de diseño Composite, el cual combina objetos dentro de una estructura jerárquica donde se encuentran almacenados los datos de los diagramas, así como el patrón de comportamiento Iterator, el cual proporciona una forma de acceder secuencialmente a los datos de los objetos y finalmente el patrón de comportamiento Visitor, el cual sirve para realizar operaciones sobre la estructura del objeto Composite, cuando se hace el recorrido y la visita a cada nodo de la estructura. 2.5 Frameworks Un framework es una estructura de soporte, en la cual otro proyecto de software puede ser organizado y desarrollado. Típicamente un framework puede incluir soporte de programas, bibliotecas y un lenguaje de software interpretado entre otros, los que ayudan a desarrollar y unir los diferentes componentes de un proyecto. 22 Capítulo 2 Marco Teórico Un framework representa una arquitectura de software que modela las relaciones generales de las entidades del dominio. Provee una estructura y una metodología de trabajo la cual extiende o utiliza las aplicaciones del dominio. Los Frameworks son diseñados con el fin de facilitar el desarrollo de software, permitiendo a los diseñadores y programadores pasar más tiempo identificando requerimientos de software que tratando con los tediosos detalles de bajo nivel de proveer un sistema funcional. Dentro de los objetivos que persigue un framework están: Acelerar el proceso de desarrollo Reutilizar código ya existente Promover el uso de patrones de diseño El desarrollo del framework ha sido exitoso en muchos dominios. Algunos ejemplos incluyen la Microsoft Foundation Classes (MFC) framework, el Object Management Group's (OMG) y el COM+ y DCOM de Microsoft. Los frameworks son los generadores de aplicación que se relacionan directamente con un dominio específico, es decir, con una familia de problemas relacionados por ejemplo la herramienta SOODA utiliza el framework de la MFC1. 2.6 Modelado de objetos Un modelo es una abstracción de algo, cuyo objetivo es comprenderlo antes de construirlo. Para construir sistemas complejos el desarrollador de software deberá utilizar el principio de abstracción para obtener diferentes vistas del sistema, obtener el modelo usando notaciones, verificar que el modelo satisfaga los requisitos del sistema y finalmente desarrollar su implementación [12]. El modelado de objetos captura la estructura estática del sistema, muestra los objetos del sistema, las relaciones entre ellos y los atributos que caracterizan a cada clase. Los modelos de objetos proporcionan una representación gráfica del sistema y sirven para documentar la estructura del sistema. Los datos globales desaparecen, por lo tanto cualquier cambio en la estructura de algunos de los datos sólo debería afectar las funciones definidas en ese mismo objeto y no en los demás, en general, un programa orientado a objetos se define en términos de objetos y relaciones de los datos y funciones que se guardan dentro de objetos, los datos están ubicados en el centro del objeto, lo cual hace que un cambio en su estructura sólo afecte funciones del mismo objeto pero no al resto de la aplicación. 1 Biblioteca de Clases Base de Microsoft 23 Capítulo 2 Marco Teórico 2.7 Características de los modelos orientados a objetos. Las metodologías se auxilian de los modelos para lograr sus objetivos, sin embargo, cabe preguntarse ¿qué es un modelo?, un modelo puede definirse como la representación gráfica y abstracta de algo real [20]. Para construir un modelo es necesario analizar detalladamente cada uno de los aspectos que interactúan en él y plasmarlos claramente en el mismo. En cualquier actividad que se realice, es de gran utilidad modelar, ya que es más barato construir modelos que construir cosas reales. El hacer uso del modelado sirve como herramienta que permite verificar toda la información de entrada y de salida utilizada en el sistema, así como identificar los procesos existentes y sus relaciones de éstos con su medio ambiente. Un buen modelo también facilita la tarea del usuario al proporcionarle una herramienta fácil de comprender y que ejemplificará la funcionalidad del sistema de desarrollo. Los modelos deben cumplir con las siguientes características que muestran su razón de ser: Deben ser gráficos pero contar con texto, es decir, el gráfico debe ser comprensible. Toda la información que de alguna forma intervenga en este modelo debe estar representada en él. Deben ser particionados, es decir un modelo debe ser realizado en diferentes niveles, cada nivel representa la profundidad con que se esté modelando o el enfoque con que se esté realizando. Capaz de minimizar la redundancia de información y de procesos. Debe poder predecir el comportamiento del sistema o de alguna de sus partes. Para desarrollar una aplicación es necesario contar con una descripción de alto nivel y de una descripción detallada de la solución propuesta y cómo dicha solución debe cumplir con los requerimientos y restricciones planteados. El diseño se centra en una solución lógica, es decir, cómo el sistema propuesto cumple con los requerimientos. El desarrollo del sistema no es una extensión del análisis mismo, se sirve de los modelos conceptuales desarrollados durante el análisis del sistema. 2.8 Conceptos básicos del modelo orientado a objetos La tecnología orientada a objetos se apoya de fundamentos de ingeniería, los cuales de manera global reciben el nombre de modelo de objetos, el cuál abarca los siguientes principios: 24 Capítulo 2 Marco Teórico 2.8.1 Abstracción La abstracción es un proceso mental que sirve para identificar ciertos elementos relevantes del problema. Su finalidad es aislar los aspectos importantes para alguna entidad y suprimir los aspectos que no lo sean. Es decir es el acto de reunir cualidades esenciales o generales de cosas similares [4]. Un buen modelo capta los aspectos esenciales del problema y omite los demás. Un modelo que contiene detalles no relevantes limita las opciones de diseño. El uso de la abstracción durante el análisis significa tratar sólo conceptos del dominio de la aplicación y no tomar decisiones de diseño antes de haber comprendido el problema [13]. 2.8.2 Encapsulación La encapsulación denominada también ocultamiento de información, significa separar los detalles externos del objeto a los cuales pueden acceder otros objetos, de los detalles internos del objeto los cuales quedan ocultos para los demás. La encapsulación evita que el programa llegue a ser tan interdependiente que un pequeño cambio tenga efectos secundarios masivos [13]. La implementación de un objeto se puede modificar sin afectar las aplicaciones que las usan. La abstracción y encapsulación son conceptos complementarios, porque mientras una se ocupa del comportamiento la otra se ocupa de la implementación que da ese comportamiento. 2.8.3 Modularidad El módulo es una construcción lógica para agrupar clases, asociaciones y generalizaciones. Los módulos capturan una perspectiva o vista de una situación. Los modelos de objetos constan de uno o más módulos, los cuales sirven para descomponer el modelo de objetos en entidades o segmentos más manejables. La modularidad según Myers, es el acto de fragmentar un programa en componentes individuales, lo cuál reduce la complejidad del sistema [7]. Considerando que un módulo es conjunto separado de diseño, es decir una construcción que se agrega a un sistema por separado de otras construcciones, pero que forman parte como un todo dentro del sistema. Los módulos sirven como contenedores físicos, en los que se declaran las clases y objetos del diseño lógico realizado. En el diseño estructurado tradicional, la modularización persigue ante todo el agrupamiento de subprogramas [7]. 25 Capítulo 2 Marco Teórico 2.8.4 Herencia. La herencia es el proceso por el cual un objeto adquiere las propiedades de otro. Esto es importante ya que es la base para la relación de las clases de manera jerárquica [8], por ejemplo una clase padre o superclase sobre otras clases hijas o subclases, esta propiedad nos permite crear nuevas clases a partir de clases existentes conservando las propiedades de la clase original y añadiendo otras nuevas. La nueva clase obtenida se conoce como clase derivada, y las clases a partir de las cuales se deriva, clases base. Además, cada clase derivada puede usarse como clase base para obtener una nueva clase derivada y cada clase derivada puede serlo de una o más clases base. La herencia interactúa también con el encapsulado. Si una determinada clase encapsula determinados atributos, entonces cualquier subclase tendrá los mismos atributos, más cualquiera que añada como parte de su especialización [10]. 2.8.5 Polimorfismo. En programación orientada a objetos se denomina polimorfismo a la capacidad que tienen objetos de diferentes clases de responder al mismo mensaje o evento. Esto significa que puede haber muchos mensajes con el mismo nombre en diferentes clases. Cada clase responde al mensaje con su código propio (o método). Justamente de ahí el nombre de polimorfismo, muchas formas de responder al mismo mensaje. También se puede aplicar a la propiedad que poseen algunas operaciones de tener un comportamiento diferente dependiendo del objeto (o tipo de dato) sobre el que se aplican. El polimorfismo sólo es aplicable si cualquiera de los posibles tipos de objetos que se invoquen tienen definida la operación empleada y los tipos de datos de entrada requeridos y los valores devueltos, más allá de cómo se empleen o calculen son compatibles entre sí. El concepto de polimorfismo se puede aplicar tanto a funciones como a tipos de datos. Así nacen los conceptos de funciones polimórficas y tipos polimórficos. Las primeras son aquellas funciones que pueden evaluarse o ser aplicadas a diferentes tipos de datos de forma indistinta; los tipos polimórficos, por su parte, son aquellos tipos de datos que contienen al menos un elemento cuyo tipo no está especificado. De manera más general. El concepto de polimorfismo se expresa a menudo mediante la frase “una interfaz, múltiples métodos”. Esto significa que es posible diseñar una interfaz genérica para un grupo de actividades relacionadas. Esto ayuda a reducir la complejidad, permitiendo que la misma interfaz sea usada para especificar una clase general de acciones [10]. 26 Capítulo 2 Marco Teórico 2.8.6 Persistencia. Se entiende por persistencia en la programación orientada por objetos como la capacidad que tienen los objetos de conservar su estado e identidad entre distintas ejecuciones del programa que los creó o de otros programas que accedan a ellos. De este modo los objetos pueden clasificarse en: Transitorios: cuyo tiempo de vida depende directamente del ámbito del proceso que los instanció. Persistentes: cuyo estado es almacenado en un medio secundario para su posterior reconstrucción y utilización, por lo que su tiempo de vida es independiente del proceso que los instanció. La persistencia permite al programador almacenar, transferir y recuperar el estado de los objetos. Para resumir, se define la persistencia como: La persistencia es la propiedad de un objeto por la que su existencia trasciende el tiempo, es decir el objeto continua existiendo después de que su creador deja de existir y/o queda sin espacio de memoria (es decir, la posición del objeto varía con respecto al espacio de direcciones en el que fue creado) [7]. 2.9 Diseño orientado a objetos En el diseño orientado a objetos los desarrolladores de software piensan más en las cosas que interactúan en el sistema en lugar de funciones u operaciones. Un proceso de diseño orientado a objetos comprende el diseño de clases de objetos y las relaciones entre estas clases [11]. El proceso de desarrollo de sistemas orientados a objetos es el siguiente: El análisis orientado a objetos comprende el desarrollo de un modelo orientado a objetos que corresponda al dominio de la aplicación. Los objetos identificados reflejan entidades y operaciones que están relacionadas con el problema a resolver. El diseño orientado a objetos comprende el desarrollo de un modelo orientado a objetos de un sistema de software para implementar los requerimientos identificados. Los objetos en un diseño orientado a objetos están relacionados con la solución al problema por resolver, pero pueden existir relaciones entre objetos del problema y algunos objetos que no se habían considerado como parte de la solución del problema, estos últimos se tienen que agregar como nuevos objetos del problema a resolver. La programación orientada a objetos consiste en llevar a cabo la implementación del diseño de software utilizando un lenguaje de programación orientado a objetos. 27 Capítulo 2 Marco Teórico El lenguaje utilizado para el desarrollo del módulo de generación de código en java y el diseño detallado de los métodos de esta tesis es en Visual C++ versión 6.0. 2.10 Métodos de análisis orientado a objetos 2.10.1 Método Booch Booch define su método como una forma de descomponer la complejidad de un sistema de manera orientada a objetos, define varios diagramas y sus respectivos símbolos y un proceso para diseñar sistemas de software que utiliza los diagramas para capturar aspectos físicos, lógicos, estáticos y dinámicos de un sistema de software, el proceso define actividades para un micro desarrollo y para un macro desarrollo que incluyen prácticas tradicionales en la elaboración de software [8]. 2.10.2 Método OMT La Técnica OMT (por sus siglas en inglés Object Modeling Technique) es un procedimiento que se basa en aplicar el enfoque orientado a objetos en todo un proceso del desarrollo de un sistema software, desde el análisis hasta la implementación. Los métodos de análisis y diseño que propone son independientes del lenguaje de programación que se emplee para la implementación. Esta tecnología puede ser aplicada en varios aspectos de implementación incluyendo archivos, bases de datos relacionales y bases de datos orientadas a objetos [14]. 2.10.3 Método OOSE La Ingeniería OOSE (por sus siglas en inglés Object Oriented Software Engineering) realizada por Jacobson, es una metodología para el análisis y diseño orientada a objetos derivada del Objectory de Jacobson. Objectory es un método propio y OOSE es una versión simplificada de la cual se dice que no es adecuada para su uso en la línea de producción. La metodología es potente y esta llena de ideas útiles e interesantes. Jacobson es uno de los mayores expertos en Análisis Orientado a Objetos en la actualidad, y sus ideas generales basadas en numerosos proyectos, no pueden ignorarse. La filosofía de empresa subyacente consiste en que las herramientas proporcionan su apoyo a las actividades dentro de tres categorías: Arquitectura, Método y Procesos. Arquitectura quiere decir la selección de las técnicas que hay que utilizar, el Método hace explícitos los procedimientos que deberían seguirse y el Proceso proporciona el escalado del Método. Todo esto a manera de analogía es lo que sucede en el mundo de la construcción. El desarrollo es progresivo e implica ciclos iterativos de análisis, construcción y pruebas. Se considera cada iteración como un cambio realizado en un sistema ya existente que implica el control de la versión y de la documentación en los niveles de módulo y de sistemas. En términos de ciclo vital, OOSE recomienda etapas de análisis, construcción y pruebas. 28 Capítulo 2 Marco Teórico 2.10.4 Lenguaje de Modelado Unificado UML. El Lenguaje de modelado UML (por sus siglas en inglés Unified Modeling Language) esta pensado para especificar, visualizar y construir los componentes que conforman un sistema de software o un modelo de negocios, con las más avanzadas metodologías y herramientas orientadas a objetos. Fue diseñado para especificar, visualizar, construir y documentar las partes de un sistema de software. El UML representa una formalización del análisis y el diseño, comprende símbolos y una gramática que define la manera en que se pueden usar esos símbolos. UML es la unificación de las metodologías BOOCH, OMT y OOSE que contiene como partes fundamentales vistas, diagramas, elementos del modelo y mecanismos generales. UML es un lenguaje de modelado, no es una metodología. UML no posee la noción de proceso, la cual es una parte importante de una metodología. El lenguaje de modelado es la notación (gráfica) de que se valen los métodos para expresar los diseños [17]. Es necesario comentar que el lenguaje de modelado es parte importante del método, es decir, no contempla el aspecto de lo que es un proceso más bien se usa para expresar el diseño. UML define una notación, que especifica de manera gráfica el diseño del modelo, por ejemplo están los diagramas de clases que representan las clases, asociación y multiplicidad de las clases. El UML es independiente del proceso sea cual fuere éste, el UML sirve para analizar y diseñar un modelo, para establecer la arquitectura y crear el plan de construcción. Los conceptos y modelos del UML pueden agruparse en las siguientes áreas: Estructura estática Comportamiento dinámico Construcciones de implementación Organización del modelo Mecanismos de extensión 2.11 Estructura estática Esta estructura define las entidades de la aplicación, sus propiedades internas, y las relaciones entre cada una de ellas. Este conjunto de construcciones es la estructura estática. Las entidades de la aplicación son modelados como clases, cada una de las cuales describe un conjunto de objetos que almacenan información y se comunican para implementar un comportamiento. La información que almacena es modelada como atributos y el comportamiento son los métodos; La estructura estática se expresa con diagramas de clases y puede usarse para generar la mayoría de las declaraciones de estructuras de datos en un programa. 29 Capítulo 2 Marco Teórico 2.12 Comportamiento dinámico El modelo dinámico examina el comportamiento del sistema que cambia través del tiempo, es decir se utiliza para especificar e implementar los aspectos del control, describiendo las secuencias de operaciones que se producen, sin tener en cuenta lo que hagan estas operaciones. El modelo dinámico es una etapa importante en lo que se refiere a los cambios que sufren los objetos y sus relaciones con el tiempo, ya que describen sus cambios internos (diagrama de estado) durante el desarrollo de la aplicación, sus relaciones temporales y de eventos entre ellos, como se comunican para mostrar el comportamiento del sistema (diagrama de colaboración y secuencial). 2.13 Construcciones de implementación Los modelos del UML tienen significado para el análisis lógico y para la implementación física. Por medio de los diagramas de implementación y despliegue se muestran los componentes de software y hardware que participan en el sistema. Un componente es una parte física reemplazable de un sistema y es capaz de responder a las peticiones descritas por un conjunto de interfaces. 2.14 Organización del modelo La información del modelo puede ser dividida en piezas llamadas paquetes. Los paquetes2 son unidades organizativas, jerárquicas y de propósito general de los modelos del UML. Pueden usarse para almacenamiento, control de acceso, gestión de la configuración y construcción de bibliotecas que contengan fragmentos de código reutilizable. Los diagramas de clases pueden incluir los paquetes para organizar y dividir el sistema en partes, para que puedan ser más fáciles de manejar. 2.15 Mecanismos de extensión El UML tiene una limitada capacidad de extensión pero que es suficiente para la mayoría de las extensiones que requiere sin la necesidad de un cambio en el lenguaje básico. Un estereotipo3 es una nueva clase de elemento de modelado con la misma estructura que un elemento existente pero con restricciones adicionales. Se usan para realizar adaptaciones y ajustar al modelo a su realidad. Las restricciones son acotaciones semánticas representadas como expresiones textuales. El UML define diferentes vistas, cada vista representa una proyección del sistema mostrando una proyección en particular, cada vista se describe en un conjunto de 2 Un paquete es una unidad de organización para poseer y manejar el contenido de un modelo. Todo elemento de un modelo esta contenido dentro de un paquete. 3 Un estereotipo es un mecanismo de extensibilidad para definir meta-clases. 30 Capítulo 2 Marco Teórico construcciones de modelado que representan un aspecto particular del sistema, las vistas se dividen en tres áreas: 1. Clasificación estructural: describe los elementos del sistema y sus relaciones con otros elementos. Los clasificadores4 incluyen clases, casos de uso, componentes y nodos. Los clasificadores proveen la base sobre la que se construye el comportamiento dinámico. Las vistas de clasificación estructural incluyen la vista estática, vista de casos de uso, la vista de implementación y despliegue [25]. 2. Comportamiento dinámico: describe el comportamiento del sistema a través del tiempo. El comportamiento puede ser descrito como una serie de cambios del sistema tomadas desde la vista estática. Las vistas de comportamiento incluyen la vista de la máquina de estados, la vista de actividades y la vista de interacción [25]. 3. Gestión del modelo: describe la organización de los modelos mismos en unidades jerárquicas. El paquete es la unidad de organización para los modelos. Tipos especiales de paquetes son los modelos y subsistemas. Área Estructural Dinámica Vista Diagrama Estática Diagrama de clases Casos de uso Casos de uso Implementación Diagrama de componentes Despliegue Diagrama de despliegue Máquina de estados Diagrama de estados Actividades Diagrama de actividades Interacción Diagrama de secuencia Diagrama de colaboración Gestión del modelo Extensibilidad Gestión del modelo Diagrama de clases Todos Todos Conceptos Clase, asociación, generalización, dependencia, realización, interfaz. Caso de uso, actor, extensión, asociación, inclusión, generalización. Componente, interfaz, dependencia, realización. Nodo, componente, dependencia, localización. Estado, evento, transición, acción Estado, actividad, transición, concurrencia, reunión. Interacción, objeto, mensaje, activación. Colaboración, interacción, rol de colaboración, mensaje. Paquete, subsistema, modelo. Restricciones, estereotipos, valores etiquetados. Tabla 2.2 Relación entre las áreas, vistas y diagramas del UML. 4 Un clasificador es un elemento del modelo que tiene identidad, estado, comportamiento y relaciones. 31 Capítulo 2 Marco Teórico 2.16 Diagramas del UML Un diagrama es la representación gráfica de un conjunto de elementos los cuales pueden estar relacionados, estos sirven para representar un sistema desde diferentes perspectivas, es decir, el diagrama muestra el conjunto de elementos que forman parte del sistema utilizando algún tipo de notación gráfica. Los diagramas son ventanas o vistas de un modelo [15]. En UML existen trece tipos de diagramas, pero aquí se hablara acerca de los diagramas que están más involucrados en el desarrollo de esta tesis. 2.16.1 Diagramas de clases Un diagrama de clases muestra un conjunto de clases, interfaces y colaboraciones, así como sus relaciones (herencia, agregación y asociaciones). Los diagramas de clases abarcan la vista de diseño estática de un sistema, muestran los atributos y métodos de las clases. Con SOODA se puede generar código en Java a partir de modelos con diagramas de clases. 2.16.2 Diagramas de casos de uso Un diagrama de casos de uso muestra un conjunto de casos de uso, actores y sus relaciones. Los diagramas de casos de uso cubren la vista de casos de uso estática de un sistema, estos son importantes en el modelado y organización del comportamiento de un sistema. Un caso de uso es algo que el actor quiere que el sistema haga [15]. 2.16.3 Diagramas de secuencias Los diagramas de secuencias corresponden a los diagramas de interacción, los que sirven para mostrar las clases u objetos a lo largo de la parte superior y los mensajes enviados entre estas clases, modelando un solo flujo a través de los objetos del sistema. Un diagrama de secuencia implica un ordenamiento en el tiempo al seguir la secuencia de mensajes entre las clases. 2.16.4 Diagramas de actividades Los diagramas de actividades muestran la estructura de un proceso o el flujo de control y los datos paso a paso. Estos cubren la vista dinámica de un sistema. Son importantes porque modelan el funcionamiento de un sistema y resaltan el flujo de control entre objetos. 32 Capítulo 2 Marco Teórico 2.17 Relaciones del UML Las relaciones en un modelo permiten mostrar como dos o más elementos se relacionan entre sí, permitiendo capturar conexiones significativas entre dichos elementos. Hay cuatro tipos de relaciones en UML: 1. 2. 3. 4. Dependencia. Asociación. Generalización. Realización. Dependencia: “Es la relación semántica entre dos elementos, en la cual un cambio a un elemento (elemento independiente) puede afectar a la semántica del otro elemento (elemento dependiente)” [7]. Las dependencias se usan en el contexto de las clases para indicar que una clase utiliza las operaciones de otra o que utiliza variables o parámetros cuyo tipo viene dado por otra clase. Las dependencias se usarán cuando se quiera indicar que un elemento utiliza a otro [8]. Gráficamente se representa por una línea discontinua, dirigida que incluye a veces una etiqueta, tal como se muestra en la figura 2.1. Figura 2.1 Dependencia. Asociación: Es la relación estructural entre clases que describe un conjunto de enlaces, los cuales son conexiones entre objetos que son instancias entre clases, es decir, que los objetos de un elemento están conectados con los elementos de otro. Dada una asociación entre dos clases, se establece una relación de un objeto de una clase con algunos objetos de otra clase. La agregación es un tipo especial de asociación que representa una relación estructural entre un nodo y sus partes. Gráficamente una asociación se representa como una línea continua, posiblemente dirigida, que a veces incluye una etiqueta, multiplicidad y nombres del rol [8], tal como se muestra en la figura 2.2. 0..1 * Departamento Figura 2.2 empleado Asociación. 33 Capítulo 2 Marco Teórico Generalización: Es una relación de especialización/generalización en la cual el elemento especializado es el hijo y se basa en la especialización del elemento especializado llamado padre. El hijo comparte la estructura y el comportamiento del padre. Gráficamente una relación de generalización se representa como una línea con una punta de flecha apuntando al padre [8], tal como se muestra en la figura 2.3. Figura 2.3 Generalización. Realización: Es una relación semántica entre clasificadores, en donde un clasificador especifica un contrato que otro clasificador garantiza que cumplirá. Se pueden encontrar relaciones de realización en dos sitios: entre interfaces y las clases y, componentes que las realizan, y entre los casos de uso y las colaboraciones que los realizan. Gráficamente una relación de realización se representa como una mezcla entre una generalización y una relación de dependencia, tal como se muestra en la figura 2.4. Figura 2.4 Realización. 2.18 Diagramas de Warnier Para diseñar cada uno de los métodos o funciones de un sistema se debe recurrir a un análisis orientado a objetos, dentro de un método debemos llevar a cabo un algoritmo que nos lleve desde un estado inicial a un estado final, donde no existen colaboraciones o responsabilidades, sino simplemente tareas a ejecutar en un cierto orden. En UML no existe un estándar para modelar el diseño de los métodos, para ello es necesario usar un diagrama que pueda describir las estructuras de control (diseño estructurado), dentro de los métodos de las clases. Los diagramas de Warnier contemplan estas características ya que es una notación dirigida por los datos, por ello en este proyecto existe una colaboración entre una herramienta de modelado orientado a objetos y la herramienta para el diseño detallado de los métodos de las clases. Los diagramas de Warnier/Orr (también conocidos como construcción lógica de programas/construcción lógica de sistemas) fueron desarrollados inicialmente en Francia por Jean Dominique Warnier y en los Estados Unidos por Kenneth Orr. Este método ayuda al diseño de estructuras de programas identificando la salida y resultado del procedimiento, y entonces trabaja hacia atrás para determinar los pasos y combinaciones 34 Capítulo 2 Marco Teórico de entrada necesarios para producirlos. Los sencillos métodos gráficos usados en los diagramas de Warnier/Orr hacen evidentes los niveles en un sistema y más claros los movimientos de los datos en dichos niveles. Los diagramas de Warnier/Orr muestran los procesos y la secuencia en que se realizan. Cada proceso se define de una manera jerárquica, es decir, consta de conjuntos de subprocesos que lo definen en cada nivel, el proceso se muestra en una llave que agrupa a sus componentes. Puesto que un proceso puede tener muchos subprocesos distintos, un diagrama de Warnier/Orr usa un conjunto de llaves para mostrar cada nivel del sistema. En la figura 2.5, se muestra la forma en que los diagramas de Warnier denotan la jerarquía y composición. Sentencia1 Sentencia2 “etiqueta” … Sentencia n Figura 2.5 Jerarquía en diagramas de Warnier. En la figura anterior se muestra como los diagramas de Warnier denotan la jerarquía, ya que Sentencia 1 se ejecuta primero antes Sentencia 2 y así sucesivamente hasta la Sentencia n, en forma secuencial en el orden en que aparecen. Para denotar la iteración en los diagramas de Warnier, se pone la condición entre paréntesis debajo de la etiqueta, como se muestra en la figura 2.6. Sentencia 1 “etiqueta” (condición de repetición) Sentencia 2 … Sentencia n Figura 2.6 Iteración en diagramas de Warnier. 35 Capítulo 2 Marco Teórico En la figura anterior se muestra la iteración, donde las sentencias se ejecutan en orden secuencial un número de veces mientras la condición sea verdadera, en el momento que la condición es falsa la iteración termina. Para denotar la estructura condicional en los diagramas de Warnier se usa el símbolo del or exclusivo como se muestra en la figura 2.7. Condición 1 “etiqueta” Condición 2 … … … Condición n … Figura 2.7 Selección en diagramas de Warnier. En los diagramas de Warnier se utiliza el símbolo ← para denotar la asignación de un valor a una variable que está a la izquierda de este símbolo. En la siguiente figura 2.8 se muestran algunos ejemplos. Como se puede observar en la figura 2.8, la información entre paréntesis indica el número de veces que se ejecutará la estructura, como se observa en la figura b), el asterisco significa fin del ciclo una vez que se cumple la condición que va después del asterisco, en la figura c) la barra significa negación de una variable. 36 Capítulo 2 Marco Teórico aux ← x Secuencial x←y x←x+2 Iteración (n veces) Imprime x y←aux *x <= 6 b) Bloque de iteración a) Bloque secuencial x←1 x>1 y←2+z Imprime y Selección ______ x>1 x←z/2 Imprime x c) Bloque de selección Figura 2.8 Diagramas de Warnier. 2.19 Herramientas CASE CASE corresponde a las iniciales de Computer Aided Software Engineering, que traducido al español significa Ingeniería de Software Asistida por Computadora. Los objetivos de las herramientas CASE son: Aumentar la productividad de desarrollo y mantenimiento de los sistemas informáticos. Mejorar la calidad del software desarrollado. Reducir el costo, tiempos de desarrollo y el mantenimiento del software. Mejorar la gestión y dominio sobre el software, en cuanto a su planeación, ejecución y control. Mejorar el archivo de datos (enciclopedia) de conocimientos (know-how) y sus facilidades de uso, reduciendo la dependencia de analistas y programadores. Automatizar : o El desarrollo del software. o La documentación. o La generación del código. o La revisión de errores. o La gestión del proyecto. 37 Capítulo 2 Marco Teórico Permitir : o La reutilización (reusabilidad) del software. o La portabilidad del software. o La estandarización de la documentación. Integrar las fases de desarrollo (ingeniería de software) con las herramientas CASE. 2.20 Objetos y UML UML es neutro tanto en los lenguajes como en la plataforma. Dispone de un soporte para lenguajes orientados a objetos (Visual C++, Java, C#, etc.), pero también es eficaz para lenguajes orientados a objetos híbridos como C++; se ha utilizado incluso para lenguajes no orientados a objetos como C. En UML podemos modelar procesos de negocios y otras aplicaciones orientadas a objetos. Microsoft Visual C++ es un entorno de programación en el que se combinan la programación orientada a objetos (C++) y el sistema de desarrollo diseñado para crear aplicaciones gráficas para Windows (SDK). Visual C++ incluye varias herramientas que lo convierten en un generador de código de C++, un conjunto de clases (Microsoft Foundation Classes, MFC) que permiten crear aplicaciones para Windows y que permiten manejar componentes de Windows. La librería de la MFC5 es una implementación que utiliza las funciones de la API de Windows, en la cual encapsula las estructuras y llamadas a dichas funciones en objetos fáciles de usar. 2.21 Ingeniería directa La mayoría de las empresas que participan en la revisión del estándar comercializaban entornos de desarrollo que ya disponían de herramientas de generación de código y vieron el potencial del UML y las posibles mejoras en sus herramientas. De la misma manera que los teóricos en modelado y representación aportaron sus ideas para la notación, las empresas se preocuparon de que ésta fuera lo suficientemente completa como para que sus herramientas de modelado y desarrollo pudieran generar código a partir de los modelos [25]. Actualmente la ingeniería directa es un tema actual en el principio del nuevo milenio que se ha ido transformando en el paradigma opcional de desarrollo para muchas organizaciones de software. Los diagramas del UML utilizan dos formas básicas: Ingeniería directa para especificar modelos a partir de los cuales construir un sistema ejecutable. Ingeniería inversa para reconstruir modelos a partir de partes de un sistema ejecutable. 5 El Anexo B de este documento presenta la arquitectura de la MFC. 38 Capítulo 2 Marco Teórico SOODA es una herramienta que permite modelar con diagramas de clases del UML aplicando ingeniería directa para transformar el diseño (en un nivel de abstracción) y a partir de dicho modelo generar código en lenguaje java. 2.22 Sooda y DDVi El objetivo principal del desarrollo de software a partir de modelos es generar código, desplazando así el uso tradicional del código fuente. Es por ello que el grupo de Ingeniería de Software del CENIDET ha estado desarrollando un ambiente de desarrollo de software orientado a objetos denominado MANGO. El proyecto contempla como protagonista principal al Lenguaje de Modelado Unificado (UML) el cual sirve para especificar el sistema computacional por medio del lenguaje de modelado, describiendo de manera formal el sistema. Entre algunos de los módulos que contempla la suite se tienen a SOODA y DDVi. SOODA es una herramienta de ingeniería de software asistida por computadora basada en el diseño orientado a objetos, que ayuda a un ingeniero de software a especificar y diseñar un sistema, utilizando parte de un lenguaje específico de modelado, que se basa en la tecnología orientada a objetos para generar código [12]. DDVi es una herramienta que en colaboración con SOODA, permite manejar un nivel más bajo de abstracción, permitiendo diseñar de manera gráfica el comportamiento de los métodos de las clases. Para el diseño detallado de los métodos se utilizan diagramas de Warnier que sirven como notación para reforzar de manera visual la comprensión del comportamiento de los métodos y ayudan a formalizar el modelo. SOODA modela diagramas de clases del UML que corresponde a la estructura estática del sistema y DDVi modela diagramas de Warnier para el diseño detallado de los métodos, es aquí donde ambas herramientas juegan un papel importante, ya que se combinan para generar código en lenguaje java. La construcción de los programas SOODA y DDVi están basadas en un grupo de clases que pertenecen a la biblioteca de clases llamada MFC de visual C++, la cual es un conjunto organizado de clases reutilizables, que ayuda a desarrollar aplicaciones de C++ para Windows [12]. 39 Capítulo 3 Desarrollo metodológico de la herramienta Capítulo 3 Desarrollo metodológico de la herramienta ____________________________________________________________ 3.1 Condiciones previas Como se vio en los capítulos anteriores, generar código a partir de un modelo con el diseño detallado de los métodos de las clases no es un problema trivial, por lo que se ha propuesto el método de desarrollo del ciclo de vida del software, partiendo del análisis de la herramienta SOODA. La problemática del desarrollo de software, en cuanto al tiempo para producir aplicaciones, ha sido uno de los problemas principales a resolver por los ingenieros de software, ya que los grandes sistemas requieren de un tiempo aún mayor. En este periodo de 40 Capítulo 3 Desarrollo metodológico de la herramienta desarrollo y uso pueden identificarse varias etapas que juntas constituyen lo que se llama el ciclo de vida del software. Una solución del problema para el desarrollo rápido de aplicaciones debe partir ante todo, de la creación de herramientas CASE que ayuden a generar código de manera automática, para que los ingenieros de software estén más aplicados al análisis y diseño del sistema y no invertir más tiempo en la codificación del sistema. Partiendo de estas reflexiones, el siguiente paso es identificar la estrategia para abordar la solución del problema. 3.2 Descripción de la metodología La metodología que aquí se propone comienza desde el proceso de analizar las clases ya creadas en las herramientas SOODA y DDVi, las que forman parte de la suite CENIDET UML MANGO, para posteriormente hacer el diseño de las clases y métodos, los que servirán para generar código en lenguaje Java a partir de un modelo utilizando los diagramas de clases de UML y una vez generado el código a nivel de clases, llamar a la herramienta DDVi para que pueda generar el código del diseño detallado de los métodos de las clases utilizando los diagramas de Warnier y terminar hasta generar completamente el código de las clases con el código de sus métodos. Por ello se consideran las siguientes etapas: 1. El diseño del modelo por medio de diagrama de clases de UML. 2. Generación de código en Java a partir del modelo. 3. La generación de código del diseño detallado de los métodos de las clases. En la generación de código en Java a partir del modelo con diagrama de clases de UML se genera un archivo de texto, éste contiene el código en Java a nivel de clases, corrigiendo los problemas que surgen en la codificación. En la generación de código en Java se implementan los métodos y clases que se detallarán más adelante. En la generación del código para el diseño detallado de los métodos de las clases se selecciona el método ya generado para introducir el código, posteriormente se genera código y se reconstruye el archivo de texto desde SOODA para tener el código en Java completo. En este proceso se contempla el hecho de que no se tiene una generación de código en el diseño detallado y en el código de clases generado, el cual considere las diferentes sentencias existentes en Java, por lo cual se proponen trabajos futuros como se verá en el capítulo 5. 41 Capítulo 3 Desarrollo metodológico de la herramienta En el desarrollo de la tesis: Herramienta de Modelado Visual Orientado a Objetos para la Generación Automática de Código en Java, se proponen las siguientes alternativas: Las características de este trabajo son las siguientes: 1. Los códigos en Java generados a partir del modelo, se guardan previamente en archivos de texto plano con el nombre del archivo solicitado y la extensión .java. 2. Si la clase que se esta creando, es la clase principal de Java, el nombre del archivo debe tener el mismo nombre de la clase con la extensión .java, es decir es la clase que contiene la función main de Java. 3. Una vez creado el modelo con diagrama de clases, donde se muestran sus atributos, métodos y asociaciones, se debe localizar dentro de una clase visualmente el nombre de cada método para enviarlos a la herramienta DDVi para el diseño detallado de los métodos. 4. Una vez creado el diseño detallado del método, se debe generar el código correpondiente en un archivo de texto plano con el nombre de la clase y el nombre del método concatenados, para diferenciar el nombre del método con el nombre de los métodos de otras clases. 5. Una vez generado el código del diseño detallado de cada método de la clase, se debe generar el código completo (código de las clases y código de los métodos) con la herramienta SOODA, para ello el sistema debe buscar el nombre del archivo de texto creado con DDVi donde se encuentra el diseño detallado del método. Si el archivo no existe se genera código sin el diseño detallado de los métodos. 3.3 Introducción al modelo conceptual del sistema Un modelo conceptual especifica claramente el propósito del proyecto, sus objetivos que sirven como base para la planificación estratégica de un sistema, de cómo se organiza y opera, muestra el dominio de la aplicación. La figura 3.1 muestra el modelo conceptual del sistema. Capa de interfaz de usuario Capa de aplicación y gestión de objetos de la MFC Capa de repositorio 42 Capítulo 3 Desarrollo metodológico de la herramienta Figura 3.1 Modelo conceptual del sistema. La figura anterior muestra el modelo conceptual del sistema que consiste en: La capa de interfaz de usuario proporciona un conjunto de herramientas de interfaz que sirven para la comunicación entre usuarios y la aplicación, en donde el usuario puede interactuar con la aplicación, generando de manera automática modelos con diagramas de clases y diagramas de Warnier para el diseño detallado de los métodos de las clases. Realiza la ingeniería directa a partir de los modelos creados generando código en lenguaje Java. La capa de aplicación y gestión de objetos de la MFC implementa el mecanismo para la integración de objetos de MFC y objetos de la aplicación, funcionando en conjunto para la identificación de los objetos del modelo creado en la primera capa, proporcionando el apoyo para la generación de código en Java. La capa de repositorio proporciona el mecanismo y estructuras para la persistencia de los objetos creados (serialización), almacenando la información de los diagramas. Este mecanismo permite integrar los datos y la aplicación de la segunda capa. 3.4 Componentes para la generación de código en Java De manera muy general la figura 3.2 muestra el procesamiento para la generación automática de código en Java a partir de un modelo con diagramas de clases y la generación automática de código en Java para el diseño detallado de los métodos de las clases con diagramas de Warnier. 43 Capítulo 3 Desarrollo metodológico de la herramienta Ingeniería directa Captura del modelo de las clases con UML Generador de código en Java. Diseño de los métodos con Warnier- Orr Generación del código de los métodos en lenguaje Java a partir de los diagramas de Warnier-Orr Recuperación del archivo generado Figura 3.2 Visión global del sistema. 44 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ 3.5 Diagrama de flujo de la metodología propuesta Para comprender el proceso de conversión del modelo gráfico a código en Java se muestran los siguientes diagramas de flujo donde podemos observar los procesos que interactúan. Crear la lista del modelo Recibir la lista del modelo creado GENERACIÓN DE CÓDIGO EN LENGUAJE JAVA Leer la lista donde esta el modelo e ir generando el archivo texto de código en lenguaje Java Abrir el archivo generado por DDVi Código generado en lenguaje Java a partir del modelo con o sin el diseño detallado de los métodos Figura 3.3 Diagrama de flujo de la metodología propuesta. 3.6 Diagrama de flujo del diseño detallado Este proceso también es automático, ya que después de haber obtenido el nombre de cada clase, sus atributos, sus asociaciones y sus métodos, se puede pasar al diseño de cada uno de los métodos anteriormente introducidos, se procede a seleccionar el nombre del método y llamar a la herramienta DDVi. En esta etapa la herramienta DDVi recibe el nombre del método y su clase correspondiente, para saber la clase a la que corresponde dicho método. En la herramienta DDVi se procede a crear el diseño del método de manera visual usando los diagramas de Warnier, de la misma manera que en la generación de código en Java con diagramas de clases, anteriormente presentado, se procede a generar código en Java para el diseño detallado del método. El diagrama de flujo que se incluye en la figura 3.4 a continuación, nos muestra el conjunto de procesos que se realizarán para generar el diseño detallado de los métodos. 45 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ Recibir el nombre de la clase y el nombre del método Crear una cadena concatenando el nombre de la clase y su respectivo método DISEÑO DETALLADO DE LOS METODOS Llamar a la herramienta DDVi y pasarle como parámetro la cadena Crear el diseño detallado del método usando diagramas de Warnier Código generado en Java correspondiente al diseño detallado del método en un archivo de texto Figura 3.4 Diagrama de flujo del diseño detallado de los métodos. 3.7 Diagrama de casos de uso del sistema. La figura 3.5 muestra el diagrama de casos de uso del sistema, su comportamiento y visualiza los componentes de éste. 46 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ Diseño detallado de métodos de clase Diseño de la arquitectura de clases <<extend>> <<extend>> <<extend>> Generación de código de los métodos Generación de código en Java Usuario del sistema <<extend>> Generación de código de las clases en Java Figura 3.5 Diagrama de casos de usos del sistema. 3.7.1 Caso de uso diseño de la arquitectura de clases Nombre del caso de uso Descripción Actores participantes Precondición Condición inicial Flujo de eventos Diseño de la arquitectura de clases Permite capturar el modelo de la arquitectura de clases usando la notación del UML y crear una lista con doble ligadura. Usuario del sistema 1. 2. 3. El actor activa el botón de dibujo de clases de la barra de herramientas de diseño. El sistema muestra el botón seleccionado y el actor puede ubicarse en la posición que desee de la ventana principal para dibujar cada clase. Haciendo click en la posición seleccionada de la ventana principal se dibuja la clase. Si desea agregar más clases, hace clic en otra posición de la ventana principal. Si ya no desea agregar más clases oprime 47 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ 4. 5. 6. 7. Condición de salida 1. Poscondición 1. el botón apuntador que se encuentra en la barra de herramientas. Haciendo doble click sobre la clase dibujada, se despliega el cuadro de diálogo propiedades. El actor captura el nombre, atributos y nombres de los métodos de la clase en el cuadro de diálogo y se guardan los datos de la clase en una lista con doble ligadura. Si el actor desea agregar más clases, oprime el botón de dibujo de clases que se encuentra en la barra de herramientas y repite los pasos 2, 3, 4, 5 y 6. Si el actor desea agregar, generalización, agregación o composición, puede seleccionar los botones de la barra de herramientas respectivamente para su diseño. El modelo creado con el diagrama de clases del UML se muestra en pantalla. El modelo con diagrama de clases se guarda en una lista con doble ligadura. 3.7.2 Caso de uso diseño detallado de métodos de clase Nombre del caso de uso Descripción Actores participantes Precondición Condición inicial Flujo de eventos Diseño detallado de métodos de clase Permite capturar el modelo con diagrama de Warnier y crear una lista con doble ligadura. Usuario del sistema Haber construido su clase contenedora. 1. Desde el cuadro de diálogo donde se capturan el los atributos y métodos de las clases, el actor selecciona el nombre del método y oprime el botón derecho del mouse, aparece una lista con la opción diseño, selecciona diseño y llama automáticamente a la herramienta DDVi para su diseño. 2. 3. 4. 5. 6. El sistema muestra la barra de herramientas que contiene el conjunto de símbolos de la notación del diseño detallado de Warnier. El actor puede seleccionar en la posición que desee de la ventana principal para dibujar cada símbolo. El símbolo elegido por el actor es insertado al final de la lista de objetos. Cada vez que se inserta un símbolo en el diseño, se verifica el anidamiento de las funciones. Si el actor inserta un símbolo que representa un else, se hace un recorrido en la lista para verificar que debe haber antes un if. Por cada sentencia de control 48 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ 7. Condición de salida 1. Poscondición 1. se verifica que exista un fin correspondiente. Después de un símbolo fin del sistema el actor ya no puede agregar más símbolos. El modelo creado con el diagrama de Warnier se muestra en pantalla. El modelo creado con la notación del diseño detallado de Warnier, se guarda en una lista con doble ligadura. 3.7.3 Caso de uso generación de código en Java Nombre del caso de uso Descripción Actores participantes Precondición Condición inicial Flujo de eventos Condición de salida Poscondición Generación de código de las clases en Java. Permite generar el código completo (clases y métodos) en Java a partir de los modelos con diagramas de clases del UML y diagramas de Warnier. Usuario del sistema Lista con doble ligadura en donde se guarda el modelo creado con el diagrama de clases. Archivo de texto en donde se guarda el código creado con el diseño detallado de Warnier. 1. El actor selecciona el botón de generación de código en Java. 2. El sistema recorre la lista con doble ligadura donde se encuentran almacenados los datos del modelo del diagrama de clases y va generando automáticamente el código en Java en un archivo de texto. Si en el momento de ir recorriendo la lista se encuentra con el nombre de algún método, busca el archivo con el nombre de la clase y el nombre del método concatenados, si lo encuentra abre el archivo y pega el código del método en el archivo texto que contiene el código de la clase. 3. El actor puede abrir el archivo de texto donde se encuentra el código en Java. 1. Se muestra en pantalla el archivo de texto generado, donde se encuentra el código completo en Java. 1. El código generado en Java se guarda en un archivo de texto. 2. El modelo creado se guarda en un archivo de diseño. 3.7.4 Caso de uso generación de código de las clases en Java Nombre del caso de uso Descripción Generación de código de las clases en Java. Permite generar código de clases en Java a partir de un 49 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ Actores participantes Precondición Condición inicial Flujo de eventos modelo con diagrama de clases del UML. Usuario del sistema Lista con doble ligadura en donde se guarda el modelo creado con el diagrama de clases. 4. El actor selecciona el botón de generación de código en Java. 5. El sistema recorre la lista con doble ligadura y va generando automáticamente el código en Java de la clase en un archivo de texto. 6. El actor puede abrir el archivo de texto donde se encuentra el código en Java. Condición de salida 2. Poscondición 3. 4. Archivo de texto generado a partir del diagrama de clases, donde se encuentra el código en Java. El código generado en Java se guarda en un archivo de texto. El modelo creado se guarda en un archivo de diseño. 3.7.5 Caso de uso para la generación de código detallado de métodos Nombre del caso de uso Descripción Actores participantes Precondición Condición inicial Flujo de eventos Generación de código detallado de métodos. Permite generar el código de los métodos de las clases en Java a partir de un modelo con diagramas de Warnier. Usuario del sistema. Lista con doble ligadura en donde se guarda el modelo creado con el diagrama de Warnier. 7. El actor selecciona el botón de generación de código en Java. 8. El sistema recorre la lista con doble ligadura y va generando automáticamente el código en Java en un archivo de texto. 9. El actor puede abrir el archivo de texto donde se encuentra el código en Java. Condición de salida 3. Poscondición 5. 6. Archivo de texto generado, donde se encuentra el código en Java del diseño detallado del método. El código generado en Java se guarda en un archivo de texto con el nombre del método. El modelo del diseño detallado de Warnier se guarda en un archivo de diseño. 3.8Arquitectura de SOODA SOODA es una herramienta CASE, que sirve para modelar sistemas con diagramas de clases usando la notación del UML. El sistema cuenta con un menú principal y una barra de herramientas que contiene los símbolos de la notación del UML, además cuenta 50 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ con un área de trabajo donde el usuario puede dibujar las clases, sus relaciones con otras clases, también permite introducir los nombres de la clases, sus atributos y métodos por medio de un cuadro de diálogo, genera código en lenguaje C. En esta tesis se realizaran las modificaciones necesarias para que SOODA genere código en Java a partir del diagrama de clases. La herramienta DDVi es una herramienta que trabaja por separado de SOODA y permite generar el código en C a partir del diseño detallado de los métodos de las clases por medio de diagramas de Warnier, para ello ofrece un menú y una barra de herramientas con la simbología de Warnier, así como un área de trabajo donde el usuario del sistema puede dibujar el diseño, generar el código en C, guardarlo y recuperarlo en un archivo de texto. En esta tesis se realizaran las modificaciones para que genere código en Java, hacer el enlace de SOODA con DDVi, pasarle como parámetro desde SOODA a DDVi una cadena concatenada con el nombre del método y su clase respectiva, para que ésta a su vez pueda crear el archivo texto con está cadena y en este archivo generar el código del diseño detallado del método, también se tuvo que hacer modificaciones a DDVi para que pueda generar código en lenguaje Java. Finalmente SOODA recupera este archivo para generar el código completo en Java el cual está formado por el código de la clase o clases y el código del método o métodos. El sistema puede almacenar los diagramas y recuperarlos, así como imprimirlos. Este esquema para la generación de código en Java se presenta a continuación en la figura 3.6. SOODA DDVi Diagrama de clases Diseño detallado Diagramas de Warnier CShape Llama a CRectangle DDVi + Posicionx : int + Posiciony : int + Dibuja () Código en Java Recuperación del archivo generado por DDVi 51 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ Figura 3.6 Esquema para la generación de código en Java. 3.9 Clases del documento-vista La arquitectura documento-vista es la característica más importante de la biblioteca de la MFC ya que proporciona los elementos para gestionar el almacenamiento de los datos y la visualización de ellos en una aplicación. La MFC separa los datos de la visualización de los datos, para ello utiliza dos clases: 1. La clase CDocument para los objetos que guardan los datos. 2. La clase CView para la visualización de los datos. Una de las cosas que facilitan esta separación documento-vista es la implementación más sencilla de las aplicaciones con más de una vista de los datos [2]. La figura 3.7 muestra la relación documento-vista. Vista Documento Actualiza Datos Figura 3.7 Esquema de la relación documento-vista. Como se observa en la figura 3.7, el documento y la vista mantienen una relación, ya que el documento almacena un apuntador a cada una de sus vistas, además la vista almacena el apuntador a su documento, esto lo hace utilizando el método GetDocument para obtener dicho apuntador. SOODA es una herramienta que está basada en la arquitectura documento-vista y por tanto contiene estas características, sin embargo existen otras clases que complementan el trabajo para formar la arquitectura como se explica más adelante en este capítulo. 52 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ 3.10 Clases para el manejo de gráficos de SOODA En el archivo de cabecera Grafico.h se utiliza un dato enumerado Simbolos que sirve para definir los iconos seleccionados, ya sea la clase, asociación, herencia, agregación, nota, apuntador, paquete, operación, atributo y dependencia. CObject CGrafico CDiagrama CSoodaDiagrama CLinea CDependenciaB1 CAgregacionB1 CRectangulo CAsociacionB1 CHerenciaB1 CClaseB1 Figura 3.8 Clases para el manejo de gráficos de SOODA. La clase CGrafico es una clase abstracta6 que es la clase base en la jerarquía de clases para el manejo de gráficos de SOODA, como se observa en la figura 3.8. Las clases CDiagrama, Clinea y CRectangulo, redefinen los métodos de la clase CGrafico los cuales son: accept, agregar, quitar, intersecta, dibujar y crearIterator; éste último permite que cada subclase pueda crear sus objetos Iterator. En el caso del método dibujar, la subclase CRectangulo redefine este método para dibujar un objeto rectangular en la pantalla de la interfaz de SOODA. El método abstracto accept se usa para que las clases que lo implementen puedan usar el patrón de diseño Visitor. En Visual C++ cuando una clase es abstracta, como en el caso de la clase CGrafico, la declaración de sus miembros es de la siguiente manera: 6 Con una clase abstracta no se pueden crear objetos. Cualquier clase que tenga una o más funciones virtuales puras es automáticamente una clase abstracta. 53 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ virtual void dibujar (CDC* pDC) = 0; Esta notación indica al compilador que este método no se implementa en la clase CGrafico, las clases derivadas de esta clase deberán implementarlo, a esto se le llama función virtual pura. La clase CDiagrama permite declarar la estructura de datos que es una lista con doble ligadura llamada mListaFiguras, que almacena referencias a otros objetos de diferentes clases. Esto lo hace por medio de la clase CTypedPtrList que es una clase de la MFC y se usa para el manejo de plantillas de colecciones7, esta clase hereda la funcionalidad de la clase CObList para el manejo de las listas, como se explicará con mayor detalle en este capítulo. La declaración es la siguiente: CTypedPtrList<CObList, CGrafico*> mListaFiguras; La clase CDiagrama también define un método virtual llamado crearIterator, el cuál crea un objeto de tipo Iterator para las subclases que implementen este método, el cuál sirve como punto de entrada a la estructura de datos para hacer el recorrido en los objetos almacenados en la estructura. La clase CLinea sirve para inicializar, obtener y guardar la posición de las coordenadas (x,y) de los objetos gráficos de líneas, como en el caso de dibujar líneas entre las relaciones de las clases cuando se usa la generalización, agregación y dependencia. Esta clase implementa al método abstracto dibujar de la clase CGrafico, el cual dibuja las líneas en la interfaz de SOODA, obteniendo las coordenadas (x,y) origen y las coordenadas (x,y) destino, este método también usa un apuntador de la clase CDC, que es un Contexto de Dispositivo Gráfico, que sirve para usar las herramientas de tipo gráfico que proporciona la clase CDC. La clase CRectangulo sirve para dibujar objetos rectangulares en la pantalla en las coordenadas que se indiquen, para ello usa la clase CRect de la MFC, esta clase fue diseñada para representar rectángulos; creando un objeto de esta clase es posible definir el tamaño del rectángulo y junto con un objeto de la clase CPoint se obtienen las coordenadas donde se quiere imprimir el dibujo en pantalla. Generalmente los dibujos se realizan por medio del método OnDraw de la clase CView, el cuál recibe como parámetro un apuntador a la clase CDC, que le sirve para usar las herramientas de dibujo que proporciona esta clase. La clase CHerenciaB1 sirve para manejar el comportamiento de herencia de manera gráfica, por medio de su constructor inicializa los atributos tales como estilo de contorno, color de texto, color de línea en color rojo, así como los valores de la posición de coordenadas mPuntoOrigen y mPuntoDestino. Esta clase implementa el método dibujar de la clase Clinea que sirve para trazar los dibujos de líneas que representan la herencia por medio de las coordenadas mPuntoOrigen y mPuntoDestino. Esta clase hereda la funcionalidad de la clase Clinea para realizar los dibujos mediante las coordenadas que indican las posiciones de los dibujos. 7 Una colección es una clase que implementa la MFC (ver anexo B), cuya instancia permite manejar estructuras de datos (arreglos, listas y mapas) que pueden estar basadas o no en plantillas. 54 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ La clase CAgregacionB1 sirve para manejar el comportamiento de agregación de manera gráfica. Esta clase hereda la funcionalidad de la clase Alinea, la que permite obtener las coordenadas que indican las posiciones para trazar los dibujos de líneas que representan la agregación. Por medio de su constructor inicializa los atributos tales como estilo de contorno, color de texto, color de línea, así como los valores mPuntoOrigen y mPuntoDestino que son las coordenadas. Esta clase implementa el método dibujar de la clase Clinea, la cual se utiliza para realizar las líneas que representan la agregación de la notación UML, por medio de las coordenadas mPuntoOrigen y mPuntoDestino. La clase CAsociacionB1 sirve para manejar el comportamiento de asociación de manera gráfica. Esta clase hereda la funcionalidad de la clase Clinea para obtener las coordenadas que indican las posiciones para realizar los dibujos de líneas que representan la asociación. Por medio de su constructor inicializa los atributos como estilo de contorno, color de texto, color de línea, roles y cardinalidad de las clases, así como los valores mPuntoOrigen y mPuntoDestino que son las coordenadas. Esta clase implementa el método dibujar de la clase Clinea para realizar las líneas que representan la asociación de la notación UML por medio de las coordenadas mPuntoOrigen y mPuntoDestino. La clase CCLaseB1 hereda la funcionalidad de la clase CRectangulo, sirve para guardar y controlar el comportamiento de la entidad gráfica Clase del diagrama de clases de UML. Esta clase es muy importante porque de aquí se derivan otras clases que tienen que ver con todo lo relacionado para guardar las propiedades de los atributos, métodos y nombres de las clases, para ello permite que clases amigas como CPaginaPropClase, CPaginaPropAtrib, CPaginaPropMetod, CGenerador, puedan realizar operaciones sobre esta clase. Para que una función sea amiga de otra clase se declara de la manera siguiente: friend class CPaginaPropClase; Una clase friend tiene acceso a los miembros private, protected y public de una clase. La clase CCLaseB1 también guarda información como el número de atributos, el número de métodos, el nombre de la clase, también declara arreglos de cadenas para guardar los nombres de los atributos, nombres de los métodos así como los tipos de acceso a los atributos y miembros de las clases. En esta clase se ponen los nombres de las clases (Clase1, Clase2..ClaseN) que se vayan creando por medio del método SetName. 3.11 Clases de la arquitectura documento/vista de SOODA La clase CDocument proporciona la funcionalidad básica para la clase CDocumento definida en la herramienta SOODA, esto se logra derivando la clase CDocumento de la clase CDocument que es una clase de la MFC que contiene la funcionalidad para almacenar los datos. La clase CDocumento esta relacionada con la clase CGenerador ya que crea una instancia de la clase CGenerador. Esta instancia creada se usa para llamar al método GeneraCodigoJava (de la clase CGenerador) por medio del manejador de mensaje 55 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ OnButtonGeneraCodigoJava que pertenece a la clase CDocumento. Esta es una forma de asociación ya que la clase CDocumento crea una instancia de la clase CGenerador y la mantiene como una variable de manera local. Esta clase también contiene la estructura de datos correspondiente al diagrama de clases que se encuentra referenciado por medio de la variable mDiagrama que es un apuntador a la clase CSoodaDiagrama. Cuando se llama al método GeneraCodigoJava por medio del manejador de mensaje antes citado, se le envía como parámetro la variable mDiagrama, como se ve a continuación: void CDocumento::OnButtonGeneraCodigoJava(){ Generajava.GeneraCodigoJava(CDocumento::mDiagrama); } Como se observa en la figura 3.9, la clase CDocumento se deriva de la clase CDocument, esto genera que la clase CDocumento herede toda su funcionalidad, es por ello que la clase CDocumento también soporta las operaciones estándar tales como crear un documento, cargarlo o guardarlo, así como poder realizar operaciones de leer y escribir datos del documento redefiniendo la función miembro Serialize de la clase CDocument que tiene esta funcionalidad. La clase CDocumento también esta relacionada con la clase CSoodaDiagrama ya que contiene un apuntador (*mDiagrama) a dicha clase, de esta forma se esta creando una colección de objetos de la clase CSoodaDiagrama, de la cual la clase CDocumento contiene la colección de vistas asociadas a la clase. “Una clase colección es una clase cuya instancia nos permite manejar conjunto de datos u objetos y se caracteriza por la forma y el tipo de elemento que puede guardar” [12]. Algunos de los métodos usados por la clase CDocumento son: OnNewDocument() : Es una función miembro de la clase CDocument que se invoca cuando el usuario crea un documento nuevo. Serialize() : Serialize es una función miembro de la clase CObject, sirve para escribir y leer datos del documento al y desde el disco. Algunos de los manejadores de mensaje usados por la clase CDocumento son: OnButtonGeneracod() : Llama al método Generacodigo() de la clase CGenerador para generar código en lenguaje C++ a partir del diagrama de clases. OnButtonGeneracodigoJava() : Llama al método GeneraCodigoJava() de la clase CGenerador para generar código en lenguaje Java a partir del diagrama de clases. 56 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ CCmdTarget CWnd CGrafico CListIterator CDocument CDiagrama CView CSoodaDiagrama CDiagramaBuilder CSrollView CDocumento CSoodaDiagramaBuilder CVista CGenerador CSoodaLButtonDown CSoodaLButtonDbClick CSoodaLButtonUp Clases de la MFC Clases de SOODA Figura 3.9 Jerarquía de clases del documento/vista de SOODA. La clase CVista sirve para representar de manera gráfica la información que se encuentra en la clase CDocumento, en esta clase se pueden cambiar las propiedades de la ventana correspondiente a la vista, también se consigue obtener un apuntador a la clase CSoodaDiagrama. La clase CVista utiliza el método GetDocument de la clase CView la cual se encarga de retornar un apuntador del documento asociado con la vista, de esta manera la clase 57 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ CVista tiene una relación con la clase CDocumento, esto permite a la clase CVista usar los métodos miembro de la clase CDocumento por medio del apuntador. La clase CVista contiene los manejadores de mensajes8 que se ejecutan en el momento de realizar un evento click sobre los botones correspondientes en la barra de herramientas de la interfaz de SOODA, cada manejador de mensajes llama al método setFiguraActivada de la clase CDocumento con el propósito de conocer el símbolo seleccionado. Cuando se llama al método setFiguraActivada por medio del manejador de mensajes correspondiente, se le envía como parámetro el símbolo seleccionado, este a su vez recibe como parámetro el tipo de dato enumerado Símbolos y lo asigna a la variable mFiguraActivada que también es del mismo tipo, de esta manera se conoce el símbolo seleccionado. Los manejadores de mensaje que contiene la clase CVista son los siguientes: OnClase() : Envía como parámetro al método setFiguraActivada el símbolo CLASE. OnButtonAsoc() : Envía como parámetro al método setFiguraActivada el símbolo ASOCIACION. OnButtonHere() : Envía como parámetro al método setFiguraActivada el símbolo HERENCIA. OnButtonPara() : Envía como parámetro al método setFiguraActivada el símbolo PARAMETRIZADA. OnButtonAgreg() : Envía como parámetro al método setFiguraActivada el símbolo AGREGACION. OnButtonNota() : Envía como parámetro al método setFiguraActivada el símbolo NOTA. OnButtonApun() : Envía como parámetro al método setFiguraActivada el símbolo APUNTADOR. OnButtonOper() : Envía como parámetro al método setFiguraActivada el símbolo OPERACIÓN. OnButtonAtri() : Envía como parámetro al método setFiguraActivada el símbolo ATRIBUTO. OnButtonDepen() : Envía como parámetro al método setFiguraActivada el símbolo DEPENDENCIA. 8 Un manejador de mensaje es una función que el programa del usuario puede implementar para responder a los mensajes cada vez que se produce un evento, para mayor explicación ver el Anexo A. 58 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ OnButtonDbClk() : Este manejador de mensajes responde al evento doble-click en la ventana de la vista, determinando sobre qué símbolo se realizó tal evento y llama al cuadro de diálogo correspondiente para introducir sus propiedades. Algunos métodos de la clase CView de la MFC usados por la clase CVista son: OnInitialUpdate() : Este método es invocado por la aplicación antes de que la vista sea visualizada por primera vez, de esta manera se inicializa la vista del documento. OnUpdate() : Este método es invocado cada vez que los datos del documento son modificados, con el fin de actualizar la información visualizada por la vista. Este método llama al método OnDraw por medio de Invalidate(). OnDraw() : Este método se usa para dibujar los datos del documento, en este caso se usa para dibujar el diagrama de clases, por tal motivo OnDraw utiliza un apuntador a la clase CDocument para obtener los datos que va a visualizar. GetDocument() : Este método retorna un apuntador de la clase CDocument asociada con la vista. 3.12 Clases en SOODA para la generación de código en Java La clase CGenerador es la clase que contiene el método GeneraCodigoJava que sirve para generar código en lenguaje Java. Este método recibe como parámetro un apuntador (*diagrama) de la clase CSoodaDiagrama. Con este apuntador, el método GeneraCodigoJava consigue obtener la lista con doble ligadura donde se almacena la información del diagrama de clases, como se observa a continuación en la figura 3.10. CListIterator<class CGrafico> CDiagrama CConstraintSolver CSoodaDiagrama CGenerador CDocument CDiagramaBuilder CSoodaDiagramaBuilder CDocumento Clase de la MFC CClaseB1 CAgregacionB1 CHerenciaB1 CAsociacionB! Clases de SOODA Figura 3.10 Clases de SOODA para la generación de código en Java. 59 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ La manera de obtener la lista, como se mencionó anteriormente, es por medio del apuntador diagrama, que es un apuntador a la clase CSoodaDiagrama. El apuntador consigue la lista por medio del método getListaFiguras y el resultado lo deja en una variable ListaFiguras que es de tipo CTypedPtrList.9 Esta clase proporciona una forma segura para representar la estructura de datos en forma de lista de doble ligadura de los objetos de la clase CObList, de esta manera se guarda en cada elemento de la lista un símbolo del diagrama y se declara de la siguiente manera: template < clase base, clase tipo> class CTypedPtrList : public clase base La MFC proporciona dos grupos de clases para implementar las colecciones: 1. Clases basadas en plantillas. 2. Clases no basadas en plantillas. Los dos grupos de clases permiten manejar listas, arreglos y mapas, la diferencia esta en que las clases basadas en plantillas son más flexibles porque permiten crear colecciones de objetos de cualquier clase, por ello se decidió utilizar la clase CTypedPtrList [12]. La clase CTypedPtrList es un template10 que permite el manejo de estructuras que no dependen de esta clase, como se explica en las siguientes líneas de texto. La clase CObList sirve para manejar listas enlazadas, es por ello que se usa esta clase para manejar la estructura de datos en forma de lista, además porque las listas derivadas de la clase CObList pueden ser serializadas. La clase CTypedPtrList permite crear una lista de apuntadores a objetos de cualquier tipo, necesita dos parámetros, la clase base y la clase tipo. Esta clase puede almacenar cualquier tipo de datos el cual se especifica en el parámetro tipo. La clase base se usa para proporcionar un tipo de seguridad para encapsular las llamadas a sus miembros (métodos de la clase base) en este caso CObList. La forma de usar la clase CTypedPtrList en el método que genera código en Java es: CTypedPtrList<CObList, CGrafico*>& ListaFiguras = diagrama->getListaFiguras(); En el método también se utiliza el objeto POSITION de la MFC, que sirve para el manejo de clases de colección. Para poder generar código en Java se necesita recorrer la lista, para ello se necesita obtener un apuntador al primer objeto de la lista, lo cual se realiza como el código que se muestra a continuación: POSITION pos = ListaFiguras.GetHeadPosition(); 9 CTypedPtrList es una clase de la MFC para el manejo de plantillas de colecciones, para mayor referencia ver el anexo B. 10 La palabra template significa plantilla que es un mecanismo de C++ que implementa la programación genérica, permitiendo que una clase pueda trabajar con tipos de datos abstractos. 60 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ Una vez obtenido el apuntador pos al primer elemento de la lista con el método GetHeadPosition(), se procede utilizar una forma de iteración mediante un ciclo while para hacer el recorrido en la lista, como se muestra en el siguiente código: while (pos != NULL){ CGrafico* pFigura = ListaFiguras.GetNext(pos); } La clase CClaseB1 contiene la información acerca de la clase que se esta creando; por ejemplo el número de atributos, el número de métodos, el nombre de la clase, la descripción, el requisito de la clase, así como el nombre del archivo texto donde se guardará el código de la clase generada. Esta clase hereda la funcionalidad de la clase CRectangulo (ver figura 3.8). El constructor de la clase CClaseB1 se encarga de inicializar algunos datos de la clase, por ejemplo los datos para el dibujo de la clase como son el tamaño del dibujo de la clase de la notación de la UML que se dibuja en la vista, el grosor del contorno, las líneas en color negro, el color de texto en color negro, el color del fondo en color amarillo, el número de atributos, el número de métodos, la descripción y el requisito de la clase. El método getSimboloAcceso() de la clase CClaseB1, se encarga de devolver el tipo de acceso de las variables de la clase, por ejemplo si es public retorna “+”, si es private retorna “-“ y si es de tipo protected retorna “#”. El método SetName() de la clase CClaseB1, recibe como parámetro el nombre de la clase en una variable de tipo cadena llamada dato y asigna dicho valor a la variable mNombre; si es la primera clase se genera el nombre CClase1, para la segunda clase se genera CClase2 y así sucesivamente, con ello se guardan los datos (atributos y métodos) para cada clase que se va creando y sirve para relacionar el método que pertenece a una clase, como se verá más adelante en este mismo Capítulo. El método GetName() de la clase CClaseB1, retorna el nombre de la clase. Por lo anteriormente expuesto, es necesario que la clase CGenerador obtenga una referencia a la clase CClaseB1 como se observa en la figura 3.10, ya que necesita parte de esta información para generar código en lenguaje Java, para ello en el método GeneraCodigoJava() de la clase CGenerador se crea un apuntador a la clase CClaseB1 utilizando un cast a dicha clase, para tener acceso a los métodos de dicha clase. La forma en que se realiza esto se muestra en las siguientes líneas de código: CClaseB1 *pClase = (CClaseB1*) pFigura; Como al ir recorriendo la lista por medio del apuntador pFigura e ir pasando la dirección de pFigura al apuntador pClase, es necesario ir creando el archivo texto como resultado de los datos obtenidos por medio del apuntador pClase, para ello se declara un objeto de la clase CStdioFile llamado ArchivoJava, y también se declara una variable cNombreArchJava de la clase CString, que servirá para guardar el nombre del archivo, 61 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ si el archivo no existe, obtiene el nombre del archivo por medio del apuntador pClase y los guarda en la variable cNombreArchJava concatenando la extensión “.java” como se muestra a continuación: cNombreArchJava = pClase->mNombre+”.java”; Con este nombre se crea el archivo, como se muestra a continuación: ArchivoJava.Open (LPCTSTR ( cNombreArchJava), CFile::modeNoTruncate | CFile::modeWrite ) ); ( CFile::modeCreate | Una vez creado el archivo se van escribiendo en él todos los datos que se vayan obteniendo durante el recorrido de la lista por medio del apuntador pClase, por ejemplo para escribir en el archivo cNombreArchJava la descripción de la clase, se hace de la siguiente manera: ArchivoJava.WriteString(“\n/*\n Descripción : “+ pClase->mDescripcion+”\n*/\n”); La clase CGenerador también contiene un método llamado BuscaRelaciones que devuelve un valor de tipo booleano. Si este método encuentra que la clase tiene alguna relación (herencia, dependencia, agregación, asociación) con otra clase, retorna un valor verdadero. Para identificar el tipo de relación al método BuscaRelaciones se le envía como parámetro un valor 1 en el caso de que exista herencia, 2 en el caso de agregación, 3 en el caso de asociación y 4 en el caso de dependencia, este lo recibe como parámetro en una variable de tipo entero llamado nModo, dependiendo del valor de esta variable llama a los métodos correspondientes que se encuentran en la clase CConstraintSolver lo cuál se explica en el siguiente párrafo. En el momento que se esta ejecutando el método GeneraCodigoJava(), llama al método BuscaRelaciones(), en dicho método existe un apuntador a la clase CConstraintSolver llamado msolver, dicha relación se observa en la figura 3.10, la clase CConstraintSolver contiene los métodos setHerencias(), setAgregaciones(), setDependencias(), setAsociaciones(), por medio de este apuntador se puede tener acceso a cada uno de los métodos y cada método se ejecuta dependiendo del valor de la variable nNumNodo que el método BuscaRelaciones() recibe como parámetro. Cada uno de los métodos antes citados obtienen los datos de las clases que tienen algún tipo de relación con la clase que se esta generando ya sea herencia, agregación, dependencia, asociación respectivamente. Por ejemplo en el método setHerencias() se consigue el nombre de la clase base y se guarda en un arreglo de cadenas cArrNombres de tipo CStringArray, la forma de hacerlo se muestra en las siguientes líneas de código: cArrNombres.Add(hija->getNombre()); 62 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ En el método setHerencias() se consigue el nombre del tipo de acceso de la clase que hereda y se guarda en un arreglo de cadenas cArrNomVars de tipo CStringArray, la forma de hacerlo se muestra en las siguientes líneas de código: cArrNomVars.Add(obtenAcceso(herencia->getAcceso())); De la misma manera se obtienen los datos de la clase para la agregación, dependencia, asociación, guardando el nombre de la clase en el arreglo de cadenas cArrNombres de tipo CStringArray respectivamente. También de la misma manera se obtiene el tipo de acceso de la clase, para la agregación, dependencia, asociación, guardando los datos en un arreglo de cadenas cArrNomVars de tipo CStringArray. Como se explicó anteriormente, cuando se ejecuta el método GeneraCodigoJava éste a su vez llama al método BuscaRelaciones() de la clase CGenerador, al cual se le envía como parámetro un valor el cual puede ser 1, 2 ,3 o 4 dependiendo del tipo de relación que se este buscando, por ejemplo si se esta buscando herencia se le envía el valor de 1 y lo recibe en una variable nModo, si esta variable es igual a 1 se llama al método setHerencias() de la clase CConstraintSolver para conseguir el nombre de la clase base y guardarlo en la variable CArrNombres de tipo CStringArray, si el tamaño de esta variable es mayor de cero, entonces quiere decir que encontró una clase base y por tanto el método BuscaRelaciones() devuelve verdadero. Acto seguido se genera el código con el nombre de la clase por medio del apuntador pClase->mNombre en donde la variable mNombre contiene el nombre de la clase y se concatena la palabra reservada extends que indica que existe herencia, la forma de hacerlo se muestra en las siguientes líneas de código: ArchivoJava.WriteString(“class “+pClase->mNombre+ “ extends”+” “); Después de generar el código anterior, se genera el nombre de la clase base el cual se encuentra en la variable cArrNombres de tipo CStringArray, para ello se utiliza un ciclo for para buscar la posibilidad de que hubieran más clases. En las siguientes líneas se muestra el código: for (int i=0; i<cArrNombres.GetSize(); i++){ ArchivoJava.WriteString(cArrNombres[i]); if (i<(cArrNombres.GetSize()-1) ArchivoJava.WriteString(“, “); } Posteriormente se imprime el constructor, los atributos y métodos de la clase. En las variables mNumAtributos y mNumMetodos ambas de la clase CClaseB1, se guardan los números de atributos y los números de métodos respectivamente, en el arreglo mAtribNombre se almacenan los tipos de atributos y en el arreglo mAtribValor se almacenan los nombres de los atributos. 63 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ 3.13 Clases para construir el diagrama de clases de SOODA Como ya se mencionó anteriormente, la clase CDiagrama representa el diagrama de clases que contiene la información donde se guarda la información del diagrama de clases, donde mListaFiguras es miembro de esta clase y es una instancia de una clase de colección basada en plantilla de la clase CTypedPtrList, la cuál se maneja como una lista con doble ligadura que contiene apuntadores a objetos, además que permite la serialización, porque hereda esta funcionalidad por medio de la clase CObList. Esta lista permite guardar en cada uno de sus elementos objetos de diferentes clases, ya que cada símbolo se representa por una clase que se deriva de la clase CFigura. La clase CFigura es importante porque es la clase base para los símbolos que forman el diagrama de clases [12]. La jerarquía de clases se observa en la siguiente figura 3.11. CObject CFigura CNota Clase1 Clases de la MFC CClase CClaseParam Clase2 Clases de SOODA Figura 3.11 Clases de SOODA para la construcción de los diagramas de clases. La clase CFigura es una clase abstracta que hereda la funcionalidad de la clase CObject, por lo que existen ventajas para aquellas clases que se derivan de esta clase, entre ellas por ejemplo se tiene el soporte de diagnóstico para ayudar a depurar información en tiempo de ejecución para determinar la clase de un objeto, creación de objetos dinámicos y soporte para la serialización. Como se mencionó anteriormente es importante porque es la clase base a partir de la cual se derivan el resto de las clases que representan los símbolos del diagrama de clases que se guardan en la estructura de datos en forma de lista. 64 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ La clase CFigura contiene los atributos mNombre que es de tipo CString y sirve para guardar el nombre del elemento (Nodo) que forma parte de la lista que es información del diagrama de clases. Los atributos de clase CPoint, mPunto1 y mPunto2 que sirven para guardar las coordenadas que sirven para localizar un elemento gráfico en la interfaz de SOODA. El atributo mSimbolo de tipo enumerado Símbolos que sirve para conocer el símbolo seleccionado y el atributo mNumNodo de tipo entero que sirve para identificar a los nodos que forman parte de la lista, este valor se usa para hacer la búsqueda de un nodo que forma parte de la lista. La clase CClase es una clase que hereda la funcionalidad de la clase CFigura. Esta clase representa a una clase dentro del diagrama de clases. Los objetos creados a partir de esta clase representan las clases que forman parte del diseño de diagrama de clases, es importante porque guarda la información de cada clase que se esta creando, para ello permite que clases amigas como CVista y CGenerador puedan realizar operaciones sobre ella. Hay que recordar que la clase CGenerador que es la clase que sirve para generar código en Java, también es una clase amiga de la clase CClaseB1 que sirve para guardar información de las clases, como se explico anteriormente en este capítulo. 3.14 Clases para el manejo de diálogos En la interfaz de la herramienta SOODA se necesita introducir información cuando se esta diseñando el modelo utilizando diagramas de clases, como por ejemplo el nombre de la clase, sus atributos y métodos, es por ello que se usan a los cuadros de diálogo11. En la figura 3.12 se muestra la jerarquía de clases de SOODA para el manejo de los recursos de diálogo. Existen diferentes cuadros de diálogo: Cuadro de diálogo modal simple. Cuadro de diálogo común de Microsoft Windows. Cuadro de diálogo de hoja de propiedad. La clase CDialog es la clase base que permite visualizar cuadros de diálogo. En la MFC todos los cuadros de diálogos son objetos que son instancias de la clase CDialog. Hay dos tipos de cuadros de diálogo: modal y no modal. Una ventana modal exige que el usuario que cierre la ventana para poder pasar a otra ventana. Una ventana no modal el usuario puede visualizar el cuadro de diálogo y retornar a otra tarea sin cancelar o cerrar el cuadro de diálogo. 11 Un cuadro de diálogo es una ventana emergente que tiene el propósito de proporcionar información al usuario u obtener información del usuario. 65 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ CWnd CDialog CPropertyPage CPaginaPropClase CPaginaPropAtrib CPaginaPropMetod Figura 3.12 Clases para el manejo de los recursos de diálogos. Como CDialog se deriva de CWnd todos los cuadros de diálogo son ventanas de tipo especial, los eventos que ocurren dentro de un cuadro de diálogo se envían al programa utilizando el mismo mecanismo de paso de mensajes que la ventana principal, sin embargo, los mensajes de cuadro de diálogo no se envían a la ventana principal del programa, para ello cada cuadro de diálogo necesita su propio mapa de mensajes y manejador. La MFC proporciona dos clases para el soporte de tipos de cuadros diálogos. La clase CPropertySheet sirve para el manejo de hojas de propiedades y la clase CPropertyPage sirve para el manejo de páginas de propiedades. La hoja de propiedades es un cuadro de diálogo para mostrar las propiedades de un objeto, estas propiedades pueden ser de lectura o de lectura y escritura. Una hoja de propiedades contiene una o más ventanas hijas llamadas páginas. Los objetos de clase CPropertySheet presentan cuadros de diálogos con pestañas, si se hace clic en una pestaña se tiene acceso a una página de propiedades. Una página de propiedades contiene controles con un grupo de propiedades, por lo que una hoja de propiedades puede contener uno o más objetos CPropertyPage. La clase CPropertyPage encapsula una sola página de una hoja de propiedad de Windows. La clase CPaginaPropClase sirve para el manejo del cuadro de diálogo para la captura de los datos de la clase que se esta creando, por ejemplo el nombre de la clase, 66 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ parámetros, requisito, descripción, nombre del archivo, también aquí se captura si la clase que se esta creando es la clase principal. Para determinar si la clase que se esta creando es la clase principal de Java existe un objeto Check Box que cuando recibe el valor verdadero después de un evento clic llama al manejador de mensajes OnCheckClaseprincipal(), en el momento que se ejecuta este manejador se pasa a la variable m_nombreArch de tipo CString el nombre del archivo que se captura en la variable mNomClase miembro del objeto Edit Box. En las siguientes líneas de código se muestra el manejador de mensajes: void CPaginaPropClase::OnCheckClaseprincipal() { UpdateData(TRUE); if (m_CheckArchPrinJava == TRUE) M_NombreArch = mNomClase; UpdateData(FALSE); } La clase CPaginaPropAtrib sirve para el manejo del cuadro de diálogo para la captura de las propiedades de los atributos de la clase, por ejemplo el tipo de acceso del atributo, el nombre del atributo, el tipo de dato y su valor inicial. Para hacer la captura de los atributos se utiliza el objeto IDC_LIST_ATRIB de la clase CDlgAtributo que se agrega a la clase CPaginaPropAtrib que utiliza el mensaje NM_RCLICK para que el manejador de mensaje OnRclickListAtrib() proceda a cargar el pequeño menú IDR_MENU_ATRIB, como se muestra en las siguientes líneas de código: CMenu oMenuOper; oMenuOper. LoadMenu (IDR_MENU_ATRIB); CMenu *pSubMenu = oMenuOper.GetSubMenu(0); La clase CPaginaPropMetod sirve para el manejo del cuadro de diálogo para la captura de las propiedades de los métodos de la clase. Para hacer la captura de las propiedades de los métodos se utiliza el objeto IDC_LIST_ATRIB de la clase CDlgAtributo que se agrega a la clase CPaginaPropMetod que utiliza el mensaje NM_RCLICK para que el manejador de mensaje OnRclickListAtrib() proceda a cargar el pequeño menú IDR_MENU_METOD, como se muestra en las siguientes líneas de código: CMenu oMenuOper; oMenuOper.LoadMenu(IDR_MENU_METOD); CMenu *pSubMenu = oMenuOper.GetSubMenu(0); Cuando se procede a diseñar al método de la clase, se tiene que llamar a la herramienta DDVi, para poder lograrlo hay que seleccionar la opción diseño del menú IDR_MENU_METOD, al seleccionar esta opción se devuelve el ID_METODOS_DISEÑO correspondiente al ID seleccionado del menú y se compara si es la opción seleccionada, se declaran dos variables de tipo CString sNombreArch y sCommandLine. En la variable sNombreArch se concatena el nombre de la clase y el nombre del método y en la variable sCommandLine se concatena el nombre del archivo ejecutable DDVi.exe junto con la variable sNombreArch, como se muestra a continuación: 67 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ CString sNombreArch, sCommandLine; sCommandLine = “DDVi.exe”; sNombreArch = mNombreClase + mListaMetod.GetItemText(mItemSelec,0); sCommandLine += “ “+ sNombreArch; char cadena[20]; memset(cadena,’\0’,20); strcpy(cadena,LPCTSTR(sCommandLine)); Finalmente se procede a llamar a la herramienta DDVi junto con el nombre de la clase y el nombre del método que se encuentran concatenados en la variable cadena, esto es así para identificar que método corresponde a que clase como se muestra a continuación: WinExec(cadena, SW_SHOWNORMAL); 3.15 Diagrama de secuencias de la captura de datos de las clases Al ejecutar el programa se inicia con la clase CSooda para crear la plantilla de documentos, se ejecuta el constructor de la clase CDocumento, el constructor de la clase CSoodaDiagrama para inicializar la variable mNombre el cual contendrá el nombre de la clase, se carga el menú principal y la barra de herramientas. En la barra de herramientas se muestran los símbolos de la notación del UML, cuando se ejecuta el evento click sobre alguno de ellos, se ejecuta el método setFiguraActivada de la clase CDocumento para guardar el símbolo seleccionado en la variable mFiguraActivada. Al presionar el símbolo de diagrama de clases de la barra de herramientas se ejecuta el objeto de la clase ClaseB1 para poner el nombre de la clase clase1 en la variable mNombreClase, el nombre del archivo mNombreArch, la descripción en la variable mDescripcion y requisito en la variable mRequisito, estos datos se capturan por medio de un cuadro de diálogo, los datos se copian a los datos del objeto de la clase CPaginaPropClase mNomClase, m_NombreArch, m_Descripcion y m_Requisito respectivamente, después se ejecuta el cuadro de dialogo para capturar los atributos de la clase utilizando el objeto IDC_LIST_ATRIB de la clase CDlgAtributo que se agrega a la clase CPaginaPropAtrib, posteriormente se procede a capturar los datos de los métodos utilizando el objeto IDC_LIST_ATRIB de la clase CDlgAtributo, que se agrega a la clase CPaginaPropMetod no importa la secuencia de captura de los datos de los atributos de la clase con respecto a los datos de los métodos, es indistinto como se puede observar en la figura 3.13 del diagrama de secuencias. 68 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ CSooda CVista CDocumento CClaseB1 CPaginaPropClase CPaginaPropAtrib CPaginaPropMetod Inicia Documento Inicia Vista Actualiza vista Actualiza documento Captura datos de la clase Actualiza datos Captura datos de los atributos {O lógico} Captura de datos de los métodos Figura 3.13 Diagrama de secuencias para capturar los datos de las clases. 3.16 Diagrama de secuencias para la creación del diagrama de clases Cuando se oprime el icono del diagrama de clases de la interfaz de SOODA se ejecuta el constructor de la clase CSoodaLButtonUp que permite crear una referencia mbuilder a un objeto de la clase CSoodaDiagramaBuilder al cual se le envía como parámetro el 69 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ diagrama que se obtiene por medio de un apuntador de la clase CDocumento, como se observa en las siguientes líneas de código: mBuilder = new CSoodaDiagramaBuilder (mDoc->getDiagrama()); Cada vez que se crea un objeto de la clase CSoodaDiagramaBuilder se ejecuta el constructor de esta clase para crear objetos de las clases CClaseB1, CHerenciaB1, CAgregacionB1, CAsociacionB1, CDependenciaB1. En el objeto de la clase CClaseB1 se pone un nombre de la clase. El objeto de la clase CSoodaDiagramaBuilder se apoya de la clase CDiagramaBuilder para construir el diagrama de clases, ya que por medio de esta clase se ejecutan los métodos de la clase CSoodaDiagrama para el diseño del diagrama de clases, obteniendo un apuntador a un objeto de la clase CSoodaDiagrama, la figura 3.14 muestra el diagrama de secuencia. La jerarquía de clases se puede ver en las figuras 3.9 y 3.10. Cuando se inserta un nuevo símbolo, en el objeto de la clase CVista se obtiene un apuntador a la clase CDocumento por medio del cuál se obtiene un apuntador a la clase CSoodaDiagrama, en esta clase se agrega el grafico a la estructura mListaFiguras que esta declarada en la clase CDiagrama y se retorna la cantidad de elementos que hay en la lista como se observa en las siguientes líneas de código: CDiagrama::mListaFiguras.AddTail(grafico)); return CDiagrama::mListaFiguras.GetCount(); En la clase CSoodaDiagrama se crea un apuntador a la clase CIterator que es una clase abstracta con apuntadores a objetos de la clase CGrafico, en esta clase se definen los métodos para hacer los recorridos en la lista, los métodos están implementados en la clase CListIterator, esta clase es de tipo template por lo que se pueden hacer recorridos de listas de diferentes objetos. En la figura 3.14 se muestra el diagrama de secuencias para la creación del diagrama de clases. En esta figura se muestran los objetos y los mensajes correspondientes a cada clase. 70 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ CSoodaLButtonUp CSoodaDiagramaBuilder CDiagramaBuilder CSoodaDiagrama CDiagrama Crea un objeto Crea objetos Crea la clase Construye el diagrama Inserta en la lista Figura 3.14 Diagrama de secuencias para la creación del diagrama de clases. 3.17 Arquitectura de DDVi La herramienta DDVi sirve para generar código en Java a partir del diseño detallado de los métodos, para ello utiliza símbolos gráficos que sirven para representar de manera visual las estructuras y datos de los programas. La arquitectura de DDVi es similar a la arquitectura de SOODA. De la misma manera que SOODA utiliza la arquitectura documento vista por medio de las clases CLevissDoc y CLevissView respectivamente. En la clase CLevissDoc se encuentra definida la lista mListaSimbolos que es de tipo CTypedPtrList, que es una clase de la MFC, que sirve para manejar la programación 71 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ genérica mediante plantillas de colecciones (templates). En la lista se guardan objetos de la clase CSimbolo, como se muestra en las siguientes líneas de código: CTypedPtrList<CObList, CSimbolo*> mListaSimbolos; La clase CSimbolo sirve para representar los elementos que forman parte del diagrama del diseño detallado, esta clase se deriva de la clase CObject de la MFC para manejar serialización. En la clase CLevissDoc también se encuentra el método InsertaSimbolo() el cual crea un apuntador a un objeto oSimbolo de la clase CSimbolo y por medio de este apuntador se hace referencia a los datos del objeto de la clase para guardar los datos, una vez obtenidos estos, se almacenan en la lista como se muestra en las siguientes líneas de código: mListaSimbolos.AddTail(oSimbolo); La clase CLevissView contiene los manejadores de mensaje de cada uno de los iconos de figuras de la barra de herramientas de DDVi, por ejemplo para el icono que representa el ciclo for tiene el manejador de mensaje Onfor() y así sucesivamente para los demás iconos. En esta clase también se encuentran los métodos para el recorrido de la lista como se muestra a continuación: POSITION pos = pDoc->mListaSimbolos.GetHeadPosition(); while (pos!= NULL){ CSimbolo* pSimbolo = pDoc->mListaSAimbolos.GetNext(pos); pSimbolo->Dibuja(pDC); } Por medio del método OnDraw() de la clase CLevissView se hace el recorrido en la lista como se explicó anteriormente y desde ahí se llama al método Dibuja() que pertenece a la clase CSimbolo, el cual sirve para dibujar en la pantalla el mapa de bits correspondiente a cada figura para ello se usa un objeto de la clase CBitmap. En la clase CLevissView se encuentra el método OnGeneracodigo() que sirve para generar código en Java, para llamar a este manejador de mensaje se oprime el icono que se encuentra en la barra de herramientas de la interfaz de DDVi y que sirve para tal propósito. La arquitectura documento/vista de la herramienta DDVi se muestra en la siguiente figura 3.15. 72 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ Clase1 Clases de la MFC Clase2 Clases de la herramienta DDVi CObject CCmdTarget CSimbolo CWnd CView CDocument CScrollView CLevissView CLevissDoc Figura 3.15 Jerarquía de clases del documento/vista de DDVi. 3.18 Funcionamiento de DDVi Cuando se llama a la herramienta DDVi desde la herramienta SOODA con la instrucción WinExec(cadena, SW_SHOWNORMAL) como se explicó anteriormente en este capítulo, en DDVi desde el método InitInstance() de la clase CLevissApp se crea el archivo, esto se logra usando la variable lpCmdLine como parámetro pasado por Windows a WinMain. Para apuntar a la línea de comando de la aplicación se usa a m_lpCmdLine para acceder a los argumentos de la línea de comando, la variable m_lpCmdLine es una variable pública de tipo LPTSTR. En las siguientes líneas se muestra el código: 73 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ BOOL CLevissApp::InitInstance() { if (m_lpCmdLine[0] == ´ ´) { //crea un documento vacío OnFileNew(); } else { //Abre un archivo pasado como parámetro en el primer //argumento //de la línea de //comando CString sCmdLine(m_lpCmdLine) I if (sCmdLine.Find(“.dis”)== -1){ OnFileNew(); } else OpenDocumentFile(m_lpCmdLine); } } Cuando se presiona un icono de la barra de herramientas de la interfaz de DDVi, se ejecuta el manejador de mensajes respectivo que se encuentra en la clase CLevissView, dentro de este manejador por medio del apuntador pDoc de la clase CLevissDoc se llama la método InsertaSimbolo() al cuál se le envía como parámetro el símbolo seleccionado, dentro de este método se crea un objeto de la clase CSimbolo y se guardan en él los datos del símbolo seleccionado, y una vez creado el objeto y almacenado los datos se inserta en la lista como se explico anteriormente, este proceso se observa en el siguiente diagrama de secuencias de la figura 3.16. Para mostrar en la interfaz de DDVi el icono seleccionado, se usan dos métodos de la clase CDocument, GetFirtViewPosition() y GetNextView(), el primer método obtiene la primera posición de la vista del documento y el segundo método sirve para iterar en todas las vistas del documento. La función regresa la vista identificada por la posición pos que es de tipo POSITION como se muestra en las siguientes líneas de código: void CLevissDoc::InsertaSimbolo(UINT nBitMap, int Nivel, CString Descrip){ CSimbolo *oSimbolo = new CSimbolo; POSITION pos = GetFirstViewPosition(); CView *pView = GetNextView(pos); } 74 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ CLevissApp CLevissView CLevissDoc CSimbolo Inicia vista Inicia documento Envia icono seleccionado Crea objeto Inserta en la lista Solicita dibujar Solicita la lista Dibuja Devuelve la lista Genera código en Java Figura 3.16 Diagrama de secuencias para la creación del diseño de los métodos. 75 Capítulo 3 Desarrollo Metodológico de la Herramienta _____________________________________________________________________________________ 3.19 Proceso de generación de código para el diseño detallado Una vez que ha sido creado el modelo con la notación de Warnier que se encuentra almacenado en la lista mListaSimbolos, se procede a generar el código en Java para el diseño detallado de los métodos de las clases. Para ello se presiona el icono que se encuentra en la barra de herramientas de la interfaz de DDVi, al presionar dicho icono se ejecuta el manejador de mensaje llamado OnGeneracodigojava() que pertenece a la clase CLevissView, dentro de este manejador se crea y se abre el archivo que fue pasado como parámetro a la herramienta DDVi desde SOODA, para ello se usa el apuntador a la clase CLevissDoc para obtener el nombre del archivo, posteriormente se obtiene la lista que se encuentra en la clase CLevissDoc, para ello se usa el método ObtenSimbolo() que pertenece también a la clase CLevissView, dentro de este método se usa un apuntador a la clase CLevissDoc para obtener la lista mListaSimbolos e ir obteniendo los símbolos, como se muestra en las siguientes líneas de código: CSimbolo* CLevissView::ObtenSimbolo(CPoint Coord){ CLevissDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); POSITION pos = pDoc->mListaSimbolos.GetHeadPosition(); while (pos !=NULL){ CSimbolo* pSimbolo =pDoc->mListaSimbolo.GetNext(pos); if (pSimbolo->mCoord.y==Coord.y) return pSimbolo; } return NULL; } Conforme se hace el recorrido en la lista se van obteniendo los símbolos de la clase CSimbolo, se van identificando y dependiendo del símbolo obtenido, se va almacenando en una variable CadCodigo que es de tipo cadena el código correspondiente a dicho símbolo. Una vez terminado el recorrido en la lista se escribe en el archivo creado por DDVi. La pregunta es como desde SOODA se puede almacenar el código generado en DDVi en el método creado en SOODA, esto se resuelve de la siguiente manera: Cuando desde SOODA se crea el método de una clase, al entrar al submenú para el diseño se le envía a DDVi el nombre del método concatenado con el nombre de la clase, este es el nombre del archivo que se crea en DDVi, al regresar a SOODA y generar el código de la clase, hace el recorrido también en una lista y en el momento que encuentra un método, busca el nombre del archivo de la clase correspondiente, lo abre y escribe en el archivo de SOODA lo que encuentra en el archivo de DDVi. Generar el código en lenguaje Java a partir de los diagramas de clases y Warnier, no es una tarea fácil, pero como se ha visto en el contenido de éste capítulo si es posible hacerlo y que mejor que probando lo que aquí se afirma. El capítulo 4 describe los casos de prueba y ahí se podrán ver los resultados obtenidos de la utilización de éste trabajo de tesis. 76 Capítulo 4 Casos de pruebas Capítulo 4 Pruebas de la herramienta _______________________________________________________________ 4.1 Introducción En este capítulo se muestran las pruebas realizadas a la herramienta, explicando los alcances obtenidos como resultado de los análisis de las pruebas, el objetivo de estas pruebas es constatar que es posible generar el código en Java a partir de los diagramas de clases del UML y código en Java para el diseño detallado de los métodos de las clases a partir de los diagramas de Warnier. Es importante recordar que para obtener los requisitos y dar soporte a los modelos se propone un esquema de ingeniería directa. Utilizando SOODA se modela el diagrama de clases del sistema. Dentro de SOODA existe la opción de acceder al diseño de los métodos llamando a la herramienta DDVi, la cual mediante los diagramas de Warnier – Orr genera el código para el diseño detallado de los métodos. Éste capítulo presenta el plan de pruebas 76 Capítulo 4 Casos de pruebas basado en el estándar IEEE Std 829-1988. La convención de nombres se utiliza durante éste capítulo para identificar los documentos del plan de pruebas. 4.2 Plan de pruebas 4.2.1 Convención de nombres El presente plan de pruebas se basa en el estándar IEEE Std 829-1998. A continuación se describen las claves para los documentos del plan de pruebas. El documento se identifica con la siguiente convención de nombres: Clave del sistema: SOODA corresponde al nombre del procedimiento para la generación automática de código en Java. Laboratorio: El laboratorio que se describe es el Laboratorio de Ingeniería de Software (LIS). Los documentos se identifican con una clave: PP Plan de pruebas CP Especificaciones de casos de prueba EP Especificación de procedimientos de prueba RI Reporte de incidentes de prueba RR Reporte de resumen de prueba Número consecutivo: Es el número obtenido para cada prueba y documento. Para describir el primer documento del plan de pruebas se utilizará el siguiente número que corresponde con la convención de nombres: SOODA LIS PP 01 4.2.2 Elementos de pruebas Diagramas de clases. Código generado a partir de los diagramas de clases. Diagramas de Warnier. Código generado a partir de los diagramas de Warnier. Herramienta. 77 Capítulo 4 Casos de pruebas 4.2.3 Características que serán probadas Se probarán los diagramas de clases que representan el conjunto de elementos del modelo que son la parte estática y los diagramas de Warnier que representan el diseño detallado de los métodos de las clases con las siguientes características: Se probará la creación de clases junto con sus atributos y métodos. Se probará que existan estructuras de secuencia, condición y repetición dentro de los diagramas de Warnier. Se probarán las relaciones entre clases que forman parte del modelo representado por el diagrama de clases de la herramienta SOODA. Código generado: Se probará que el código generado tenga correspondencia con el diagrama de clases. Se probará que el código generado del método tenga correspondencia con el diagrama de Warnier. Se probará que los códigos generados tanto de los diagramas de clases, como de los métodos estén libres de errores de sintaxis. 4.2.4 Características que no se probarán Diagramas de clases y Warnier: No se probará que los diagramas de clases y Warnier estén semánticamente correctos. Código generado: Probar la lógica del código. Probar la compilación del código. 4.2.5 Enfoque El procedimiento para la generación automática de código en Java a partir de un modelo con diagramas de clases y de los diseños de los métodos con diagramas de Warnier, serán probados comparando los códigos de un modelo existente contra el código generado por las herramientas SOODA y DDVi. 78 Capítulo 4 Casos de pruebas 4.2.6 Criterios de éxito o fracaso 4.2.6.1 Los criterios de éxito El éxito es generar código en lenguaje Java a partir de un modelo con diagramas de clases del UML y generar código en lenguaje Java del diseño detallado de los métodos a partir de diagramas de Warnier que estén libres de errores y tengan correspondencia con sus respectivos modelos. 4.2.6.2 Los criterios de fracaso Se consideraron fracasos los archivos de código que tenían errores de sintaxis y que no tenían similitud con los modelos creados con diagramas de clases y diagramas de Warnier. 4.2.7 Criterios de la suspensión y requisitos para la reanudación Detectar errores de sintaxis en la generación de código en lenguaje Java. 4.2.8 Entregables de pruebas Los documentos entregables son los siguientes a) b) c) d) e) Plan de pruebas Especificaciones de casos de pruebas Especificación de procedimientos de pruebas Reporte de incidentes de prueba Reportes de resumen de prueba 4.2.9 Tareas de pruebas 1. 2. 3. 4. 5. Seleccionar el caso de estudio: el sistema simulador del cajero automático. Seleccionar los casos de prueba. Realizar el procedimiento de prueba Comparar resultados Obtener conclusiones. 79 Capítulo 4 Casos de pruebas 4.2.10 Necesidades del entorno Los sistemas elaborados e Visual C++ trabajan en el Sistema Operativo Windows. RAM 256 como mínimo. El sistema está instalado en un equipo marca Toshiba con las siguientes características: Intel® Pentium(R) 4 CPU 3.00 GHz Velocidad de bus 800 MHz Memoria RAM: 1024 MB Disco duro: 74.53 GB 4.2.11 Riesgos y contingencias Riesgos: Entrega retrasada del sistema. Que los diagramas de actividad del caso de prueba estén mal elaborados. 4.2.12 Aprobaciones Para implementar el presente plan de pruebas, es necesario que tenga la aprobación del director de la tesis, el Dr. Máximo López Sánchez. 4.3 Especificaciones de casos de prueba (CP) Se seleccionó como caso de estudio un sistema simulador de cajero automático (ATM, Automated Teller machine) del departamento de matemáticas y ciencias de la computación (http://www.math-cs.gordon.edu/courses/cs211/ATMExample/) por el profesor Rusell C. Bjork en la materia de desarrollo orientado a objetos. Este sistema proporciona funcionalidades como las mostradas en la siguiente figura y consisten en iniciar sistema (System startup), cerrar sistema (System Shutdown), iniciar sesión (Session), realizar transacciones (Transaction), retirar (Withdrwall), depositar (Deposit), transferir (Transfer) y consultar (Inquiry). 80 Capítulo 4 Casos de pruebas Figura 4.1 Casos de uso del caso de estudio: Cajero automático [24]. El sistema completo esta desarrollado en Java y para el lenguaje C++ estándar no está completo. El código posee documentación UML de los diagramas de clases, interacción, estados, entre otros. Los diagramas de clases sirven para representar los métodos de las clases. Los diagramas de clases (ver figura 4.2) del cajero permiten conocer la estructura del sistema. 81 Capítulo 4 Casos de pruebas Figura 4.2 Diagrama de clases del cajero automático [24]. 82 Capítulo 4 Casos de pruebas La tabla 4.1 describe los casos de prueba que fueron seleccionados de las clases del cajero automático. Las características corresponden al tipo de flujo y el tipo de estructuras que serán probadas por método. Caso de prueba Clase CP1 Card método Card() getNumber() CP2 Status toString() CP3 ReceiptPrinter PrintReceipt() Características Flujo secuencial y retorno de valores. Flujo secuencial sin retorno de valores. Contiene condicionales anidadas. Contiene estructuras de repetición. Tabla 4.1 Casos de prueba definidos para la herramienta SOODA y DDVi. 4.4 Especificación de procedimientos de prueba (EP) Los pasos a seguir en el procedimiento de prueba son los siguientes: 1. Definir los casos de prueba que contengan estructuras básicas de secuenciación, repetición y selección para ser modeladas con diagramas de clases. En SOODA-LISCP-00 se definieron los casos de prueba CP1, CP2, CP3. 2. Obtener el código original en Java de los casos de prueba que se van a modelar. 3. Generar el diagrama de Warnier que corresponde al diseño detallado de los métodos de los casos de prueba con la herramienta DDVi. 4. Generar el código completo en Java (clases y métodos) con la herramienta SOODA y DDVi. 5. Evaluar los resultados obtenidos del código generado en Java a partir de los modelos con diagramas de clases y diagramas de Warnier. 6. Revisar la sintaxis. 4.4.1 EP01. Clase Card: Métodos Card() y getNumber() Paso 1. El paso uno del procedimiento de prueba fue realizado en la tabla 4.1. Paso 2. El código original de la clase Card fue extraído de [24] se encuentra en la siguiente figura 4.3. 83 Capítulo 4 Casos de pruebas public class Card { /** Constructor * * @param number the card number */ public Card(int number) { this.number = number; } /** Accessor for number * * @return the number of the card */ public int getNumber() { return number; } /** Card number encoded on the card */ private int number; } Figura 4.3. Código de la clase Card obtenido de [24]. Paso 3 y 4. Modelado y generación de código con SOODA y DDVi de la clase Card con sus métodos Card() y getNumber() como se observa en la figura 4.6. a. diagrama de clase. Una vez que se ha capturado el modelo con el diagrama de clases con SOODA, se procede a seleccionar el método para iniciar con el diseño detallado de los métodos getNumber() y Card(). Haciendo clic en la opción diseño se llama a DDVi como se observa en la siguiente figura 4.4. En la figura 4.5 se observa la interfaz de usuario para el diseño del método getNumber() con DDVi. 84 Capítulo 4 Casos de pruebas Figura 4.4 Cuadro de diálogo para llamar a DDVi. Figura 4.5 Diseño del método getNumber() con DDVi En la siguiente figura 4.6 se observa el código generado para el método getNumber() de la clase Card a partir de los modelos creados con SOODA y DDVi. 85 Capítulo 4 Casos de pruebas /* Declaración de la clase. Código generado por SOODA */ /*Descripción : Código generado por SOODA */ import java.lang.*; import java.io.*; class Card { // Atributos private int number; // Metodos de la clase Card // constructor public Card() { number=0 ; } public Card(int number) { //Código this.number = number; } public int getNumber() { //Código return number; } } b. Código generado con SOODA y DDVi. Figura 4.6 Modelado y generación de código de la clase Card y sus métodos Card() y getNumber(). Paso 5. Se implementó con JCreator debido a que los errores de sintaxis son marcados de inmediato al compilar el programa y se puede observar en la figura 4.7. 86 Capítulo 4 Casos de pruebas Figura 4.7 Revisión de sintaxis con JCreator. Paso 6. Desde la herramienta SOODA se puede crear la clase principal para realizar la ejecución del código como se observa en la figura 4.8. Figura 4.8 Cuadro de diálogo para la creación de la clase principal de Java. 87 Capítulo 4 Casos de pruebas Se ejecutó la compilación del archivo con JCreator para mostrar los errores de sintaxis y se puede observar el resultado en la figura 4.9. Se observa que en el proceso de compilación no se detectaron errores de sintaxis. Figura 4.9 Revisión de la sintaxis con JCreator. Prueba Manual del código generado 1. Se crea un objeto usando la referencia ob y se le envia al constructor del objeto un valor 10. 2. Se ejecutó el constructor Card(int number) que recibe un parámetro y ejecutó la instrucción this para inicializar el dato del objeto con un valor 10. 3. El atributo number es inicializado con un valor 10. 4. Se invoca al método get Number() para obtener el valor del atributo number. Ejecución del programa: Se probó la ejecución del código con JCreator para conocer paso a paso la ejecución del programa y poder realizar las pruebas como se muestra a continuación. Se agregó la impresión del mensaje en la ejecución de la instrucción como se muestra a continuación en la figura 4.10. 88 Capítulo 4 Casos de pruebas Figura 4.10 Ejecución del código con JCreator. 4.4.2 EP02. Clase Status: Método toString() Paso 1. El paso uno del procedimiento de prueba fue realizado en la tabla 4.1. Paso 2. El código original de la clase Status fue extraído de [24] se encuentra en la figura 4.11. 89 Capítulo 4 Casos de pruebas public abstract class Status { /** Create a printable string representing this status * * @return string representation */ public String toString() { if (isSuccess()) return "SUCCESS"; else if (isInvalidPIN()) return "INVALID PIN"; else return "FAILURE " + getMessage(); } public abstract boolean isSuccess(); public abstract boolean isInvalidPIN(); public abstract String getMessage(); } Figura 4.11 Código de la clase Status obtenido de [24]. Paso 3 y 4. Modelado y generación de código con SOODA y DDVi del método toString() de la clase Status. a. diagrama de clase. Una vez que se ha capturado el modelo con el diagrama de clases con SOODA, se procede a seleccionar el método para iniciar con el diseño detallado del método toString(). Haciendo clic en la opción diseño se llama a DDVi como se observa en la siguiente figura 4.12. En la figura 4.13 se observa el diseño del método toString() con DDVi. 90 Capítulo 4 Casos de pruebas Figura 4.12 Cuadro de diálogo para llamar a DDVi. Figura 4.13 Diseño del método toString() con DDVi 91 Capítulo 4 Casos de pruebas En la siguiente figura 4.14 se observa el código generado para el método toString() de la clase Status a partir de los modelos creados con SOODA y DDVi. /* Declaración de la clase. Código generado por SOODA */ /* Descripción : Codigo generado por SOODA y DDVi */ import java.lang.*; import java.io.*; class Status { // Atributos // Metodos de la clase Status // constructor Status() { } public String toString() { //Código if (isSuccess()) { return "SUCCESS"; } else { if (isInvalidPIN()){ return "INVALID PIN"; } else { return "FAILURE"+ getMessage(); } } } } b. Código generado con SOODA y DDVi. Figura 4.14 Modelado y generación de código de la clase Status y su método toString(). Paso 5. Se implementó con JCreator debido a que los errores de sintaxis son marcados de inmediato como se observa en la figura 4.15. 92 Capítulo 4 Casos de pruebas Figura 4.15 Revisión de la sintaxis con JCreator. Como se observa en la figura 4.15, que en el código generado por SOODA y DDVi comparado con el código original, no existe la declaración de la clase abstracta y los métodos abstractos, por lo que se muestran tres errores ya que en SOODA no se pueden declarar clases abstractas, por lo que para efectos de esta prueba se puede capturar desde el IDE del JCreator. Paso 6. Desde la herramienta SOODA se puede crear la clase principal para realizar la ejecución del código como se vio en la figura 4.6. Pero cabe aclarar que no se pueden crear objetos de una clase abstracta en Java. El propósito de estas pruebas no es compilar el código generado por SOODA y DDVi sino más bien mostrar que el código generado por SOODA y DDVi esta libre de errores. 4.4.3 EP03. Clase ReceiptPrinter: Método PrintReceipt() Paso 1. El paso uno del procedimiento de prueba fue realizado en la tabla 4.1. Paso 2. El código original de la clase ReceiptPrinter fue extraído de [24] se encuentra en la siguiente figura 4.16. 93 Capítulo 4 Casos de pruebas import simulation.Simulation; public class ReceiptPrinter { /** Constructor */ public ReceiptPrinter() { } /** Print a receipt * * @param receipt object containing the information to be printed */ public void printReceipt(Receipt receipt) { Enumeration receiptLines = receipt.getLines(); // Animate the printing of the receipt while (receiptLines.hasMoreElements()) { Simulation.getInstance().printReceiptLine( ((String) receiptLines.nextElement())); } } } Figura 4.16 Código de la clase ReceiptPrinter obtenido de [24]. Paso 3 y 4. Modelado y generación de código con SOODA y DDVi del método PrintReceipt() de la clase ReceiptPrinter. a. diagrama de clase. 94 Capítulo 4 Casos de pruebas Una vez que se ha capturado el modelo con el diagrama de clases con SOODA, se procede a seleccionar el método para iniciar con el diseño detallado del método printReceipt(). Haciendo clic en la opción diseño se llama a DDVi como se observa en la siguiente figura 4.17. En la figura 4.18 se observa el diseño del método printReceipt() con DDVi. Figura 4.17 Cuadro de diálogo para llamar a DDVi. Figura 4.18 Diseño del método printReceipt() con DDVi. 95 Capítulo 4 Casos de pruebas En la siguiente figura 4.19 se observa el código generado para el método PrintReceipt() de la clase ReceiptPrinter a partir de los modelos creados con SOODA y DDVi. /* Declaración de la clase. Código generado por SOODA */ /* Descripción : Código generado por SOODA y DDVi */ import java.lang.*; import java.io.*; class ReceiptPrinter { // Atributos // Metodos de la clase ReceiptPrinter // constructor public ReceiptPrinter() { } void printReceipt(Receipt receipt) { //Código Enumeration receiptLines = receipt.getLines(); while (receipLines.hasMoreElements()) { Simulation.getInstance().printReceiptLine( ((String) receiptLines.nextElement())); } } } b. Código generado con SOODA y DDVi. Figura 4.19 Modelado y generación de código de la clase ReceiptPrinter y su método printReceipt() Paso 5. Se implementó con JCreator debido a que los errores de sintaxis son marcados de inmediato y se puede observar en la figura 4.20. 96 Capítulo 4 Casos de pruebas Figura 4.20 Revisión de la sintaxis con JCreator. Como se puede observar en la figura 4.20, se marcan cuatro errores, donde menciona que no puede resolver el símbolo variable Simulation, no puede resolver el símbolo variable receiptLines, no puede resolver el símbolo class Enumeration y no puede resolver el símbolo class Receipt y esto es debido a que necesita los paquetes banking.Balances, banking.Receipt, java.util.Enumeration y el paquete simulation.Simulation este último no esta disponible para descarga. 4.5 Reporte de incidentes de prueba (RI) Se encontró que en el código generado por SOODA en la declaración de las clases definidas por el usuario no comienza con la palabra reservada public. En el código generado por SOODA las clases no pueden ser declaradas con la palabra clave abstract. En el código generado por SOODA los métodos no pueden ser declarados con la palabra clave abstract. 97 Capítulo 4 Casos de pruebas La herramienta JCreator permite identificar errores de sintaxis al momento, es por ello que se utilizo esta herramienta para la revisión de sintaxis del código generado con SOODA y DDVi. En el código del cajero automático [24] no se encuentra disponible para descarga el código del paquete simulation. En el primer caso de prueba, se creo el método main para probar la ejecución del programa. 4.6 Reportes de resumen de pruebas (RR) En el modelado del método toString de la clase Status con DDVi, se encontró que no se pueden escribir sentencias else if. Sin embargo en el modelado de las sentencias else if se puede adaptar con una sentencia if anidada dentro de una sentencia else. La sintaxis del código generado por SOODA y DDVi fue comprobada con la herramienta JCreator. 4.7 Conclusiones del capítulo En el caso de prueba CP1 el tipo de estructuras de control que se modeló es de tipo secuencial, por lo tanto la prueba resultó un éxito porque se creó el método main para comprobar la ejecución del programa. El caso de prueba CP2 tiene estructuras de condición anidadas, las cuales fueron creadas con DDVi, los errores de sintaxis que genera JCreator se deben a que en la herramienta SOODA no se pueden declarar clases y métodos abstractos, esto es posible hacerlo manualmente desde JCreator, pero se concluye que la representación de las estructuras en el código fuente generado en Java fue correcto. Por último en el caso de prueba CP3 con la estructura de repetición while la cual fue creada con DDVi se detecta que no hubieron errores de sintaxis en la representación de ésta estructura, se concluye que el código fuente generado en Java fue correcto. Los errores que la herramienta JCreator genera se deben a que no se reconocen los métodos que están dentro del paquete Simulation el cual no esta disponible para descarga. 98 Capítulo 5 Resultados Capítulo 5 Resultados _______________________________________________________________ 5.1 Introducción Con el desarrollo de esta herramienta CASE, se ha podido generar código en lenguaje Java a partir de los diagramas de clases del UML así como también el código del diseño de los métodos de las clases por medio de los diagramas de Warnier, que es la aportación de este trabajo como se mencionó anteriormente en el Capítulo 1. 99 Capítulo 5 Resultados 5.2 Conclusiones De la generación del código se puede concluir lo siguiente: Con SOODA es posible generar las estructuras de clases en lenguaje Java a partir de un modelo con diagrama de clases. Con SOODA usando los diagramas de clases se puede modelar para crear herencia (generalización) entre las clases. Con SOODA usando los diagramas de clases se puede modelar para realizar asociaciones entre las clases (agregación, composición). Con SOODA usando los diagramas de clases se crean automáticamente el constructor, los atributos y los métodos de las clases. Con SOODA usando los diagramas de clases se crean los accesos a los datos de las clases los cuales pueden ser public, private y protected. Con DDVi usando los diagramas de Warnier se genera código en Java dentro de los métodos de las clases. Con DDVi usando los diagramas de Warnier se puede representar de manera visual las estructuras de control que forman parte del método de la clase. Representando las estructuras de control con los diagramas de Warnier dentro de los métodos de las clases, se puede generar código en Java a partir del modelo. Al generar código en Java, se crea un archivo texto con la extensión .java. La extensión de este archivo permite que los IDEs como JCreator, Kawa, Eclipse puedan interpretar el código en Java. 5.2.1Beneficios obtenidos Los beneficios obtenidos del presente trabajo fueron: 1. Se ha demostrado que el código generado a partir de los diagramas de clases y diagramas de Warnier esta libre de errores de sintaxis. 2. El diseño de los métodos con diagramas de Warnier permite representar las estructuras básicas de secuenciación, repetición y selección en código Java. 3. Se obtuvo una forma de comparar que el código fuente de las estructuras básicas de secuenciación, repetición y selección generado contra el modelo propuesto es casi el mismo. 4. Las herramientas SOODA y DDVi fueron un medio para automatizar el proceso de generación de código en Java a partir de un modelo. 100 Capítulo 5 Resultados 5.2.2 Limitaciones Las limitaciones son: 1. No se implementó la creación de paquetes. 2. No se verifica la declaración de los atributos de las clases dentro de los métodos. 3. No se implementó la creación de interfaces. 4. No se implementó la creación de clases y métodos abstractos. 5.3 Trabajos futuros Durante el desarrollo de la herramienta se ha podido comprobar la importancia del papel de la ingeniería de software en el desarrollo de los sistemas de software, así como la necesidad para crear estándares que sirvan para el desarrollo de sistemas más eficientes, de la importancia de seguir un proceso formal utilizando una notación estándar como el UML. Esta tesis abre áreas de conocimiento para continuar con trabajos futuros que aporten los beneficios que ayudarán a complementar el perfeccionamiento de la herramienta. Dentro de los trabajos futuros se considera lo siguiente: 1. Que la herramienta tenga la capacidad de soportar otros diagramas de clases del UML. 2. Que la herramienta pueda generar código en otros lenguajes como C#, o Delphi. 3. Que la herramienta sea compatible con otras herramientas CASE existentes. 4. Que la herramienta tenga la funcionalidad para crear clases y métodos abstractos. 5. Que la herramienta pueda crear paquetes agrupando las clases generadas. 101 Dedicatoria A mis padres María Dina y Luis que con su amor, dedicación y paciencia, me formaron y enseñaron acerca del valor y el respeto a la vida, que dieron su esfuerzo en todo momento para hacer de mí una persona de bien. A mi hermano Jorge Luis Morales Mancilla por sus consejos, por su confianza, su estímulo y apoyo que siempre me ha brindado, a mis hermanas Dora Lucia Morales Mancilla y Elvia Salas Mancilla por brindarme su apoyo moral e incondicional en los momentos más difíciles de mi vida. A mi hijo José Alberto, a mis hijas Valeria, Carolina y Andrea, que son el motor y fuente de inspiración para seguir luchando y dar lo mejor de mí en esta vida. A mi compañero de trabajo Ing. Germán Venegas Robles que siempre me ha estado motivando para terminar la tesis con su comentario de que se tiene que tener disciplina como lo hace el maestro de marimba de la escuela. Al Dr. Enrique Hernández Maldonado que con sus consejos me ha orientado y apoyado para continuar adelante y buscar nuevos retos en esta vida. Al M.A. José Ramón Velásquez Moreno, que me dio su apoyo y respaldo en uno de los momentos más difíciles de mi vida. Al Ing. Lamberto González Peña alias el sapo, que siempre me esta molestando, pero que es un gran amigo sincero. Y a todos mis amigos y compañeros que me han brindado su amistad y motivación para no sentirme solo y seguir adelante para alcanzar mi meta, les dedico este trabajo. Glosario de términos AOO Análisis orientado a objetos. API Interfaz de Programación de Aplicaciones por sus siglas en ingles Application Program Interface, es una interfaz basada en llamadas la cual representa un conjunto de funciones que ofrece todos los servicios del sistema que Windows hace. CASE Ingeniería del Software Asistida por Computadora por sus siglas en ingles Computer Aided Software Engineering. CENIDET Centro Nacional de Investigación y Desarrollo Tecnológico. DDVi Diseño Detallado Visual, es una herramienta de software desarrollada en CENIDET por el grupo de ingeniería de software que a partir de los diagramas de Warnier genera código de los métodos de las clases en lenguaje C. DLL Biblioteca de Enlace Dinámico por sus siglas en ingles Dynamic Linking Library. IDE Entorno de Desarrollo Integrado por sus siglas en ingles Integrated Development Enviorenment. IDL Lenguaje de Especificación de Interfaces por sus siglas en ingles Interface Definition Language. InverDDVi Es una herramienta de software desarrollada en CENIDET que utiliza un modelo de ingeniería inversa para la obtención de diseño detallado en diagramas de Warnier basado en Leviss para código C. Pertenece a la suite MANGO. Inverjava Realiza ingeniería inversa a partir de código Java para la obtención de los diagramas de clases. Pertenece a la suite MANGO. InverSOODA Herramienta de software desarrollada en CENIDET que realiza ingeniería inversa de código fuente en C++ para obtener el diseño de diagramas de clases y Warnier. LEVISS Es un generador de código para lenguaje C utilizando diagramas de Warnier para el diseño detallado de funciones desarrollado en CENIDET. MANGO Ambiente de desarrollo orientado a objetos elaborado en CENIDET por el grupo de ingeniería de software. viii MFC Microsoft Foundation Classes, es una biblioteca de clases que encapsula las funciones de la API de Windows, para crear y manipular objetos Windows. ODL Lenguaje de definición de objetos por sus siglas en ingles Object Definition Language. OMT Técnica de Modelado de Objetos por sus siglas en ingles Object Modeling Technique. POO Programación Orientada a Objetos por sus siglas en ingles Object Oriented. SOODA Modelado visual orientado a objetos de los diagramas de clases elaborado en CENIDET por el grupo de ingeniería de software. SCUML Suite CENIDET UML elaborado en CENIDET por el grupo de ingeniería de software. UML Lenguaje de Modelado Unificado por sus siglas en ingles Unified Modelling Language. Es un lenguaje gráfico para visualizar, especificar, construir y documentar un sistema de software. XML Lenguaje de marcas extensible por sus siglas en ingles Extensible Markup Language. ix Contenido Contenido…………………………………………………………………………….. i Índice de figuras……………………………………………………………………… Índice de tablas………………………………………………………………………. Glosario de términos…………………………………………………………………. Resumen……………………………………………………………………………… Abstract………………………………………………………………………………. v vii viii x xi Capítulo 1 Introducción y antecedentes ................................................................. 1.1 Introducción……………………………………………………………… 1.2 Antecedentes………………...………………………………………….... 1.3 Planteamiento del problema……. ............................................................. 1.4 Objetivos……............................................................................................. 1.5 Estado del arte…..……....………………………………………………... 1.6 Propósito del proyecto…..……....……………………………………….. 1.7 Justificación…..………....……………………………………………….. 1.8 Beneficios…………………………..……………………………………. 1.9 Alcances y limitaciones del proyecto……………………………………. 1.10 Organización de la tesis…………………………………………………. 1 1 2 4 5 5 16 16 17 17 18 Capítulo 2 Marco Teórico ....................................................................................... 2.1 Lenguaje de programación ......................................................................... 2.2 Importancia del modelado .......................................................................... 2.3 Desarrollo basado en componentes ............................................................ 2.4 Patrones en la ingeniería de software……………………………………. 2.5 Frameworks……………………………………………………………… 2.6 Modelado de objetos ................................................................................... 2.7 Características de los modelos orientados a objetos…………………….. 2.8 Conceptos básicos del modelo orientado a objetos……………………… 2.8.1 Abstracción ........................................................................................... 2.8.2 Encapsulación ....................................................................................... 2.8.3 Modularidad ......................................................................................... 2.8.4 Herencia……………………………………………………………… 2.8.5 Polimorfismo…………………………………………………………. 2.8.6 Persistencia…………………………………………………………… 2.9 Diseño orientado a objetos ......................................................................... 2.10 Métodos de análisis orientados a objetos………………………………… 2.10.1 Método Booch ..................................................................................... 19 19 20 20 21 22 23 24 24 25 25 25 26 26 27 27 28 28 i 2.10.2 Método OMT………………………………………………………... 2.10.3 Método OOSE……………………………………………………….. 2.10.4 Lenguaje de modelado unificado UML……………………………… 2.11 Estructura estática ....................................................................................... 2.12 Comportamiento dinámico ......................................................................... 2.13 Construcciones de implementación……………………………………… 2.14 Organización del modelo……………..………………………………….. 2.15 Mecanismos de extensión………………………………………………... 2.16 Diagramas del UML ................................................................................... 2.16.1 Diagramas de clases…………………………………………………. 2.16.2 Diagramas de casos de uso………………………………………….. 2.16.3 Diagramas de secuencias……………………………………………. 2.16.4 Diagramas de actividades…………………………………………… 2.17 Relaciones del UML……………………………………………..………. 2.18 Diagramas de Warnier…………………………………………………… 2.19 Herramientas Case……………………………………………………….. 2.20 Objetos y UML………………………………………………………….. 2.21 Ingeniería directa………………………………………………………… 2.22 Sooda y DDVi…………………………………………………………… 28 28 29 29 30 30 30 30 32 32 32 32 32 33 34 37 38 38 39 Capítulo 3 Desarrollo Metodológico de la herramienta ........................................ 3.1 Condiciones previas .................................................................................... 3.2 Descripción de la metodología…………………………………………... 3.3 Introducción al modelo conceptual del sistema.…………………………. 3.4 Componentes para la generación de código en java……………………... 3.5 Diagrama de flujo de la metodología propuesta ..………………………. 3.6 Diagrama de flujo del diseño detallado..………………………………… 3.7 Diagrama de casos de uso del sistema…………………………………… 3.7.1 Caso de uso diseño de la arquitectura de clases………………………… 3.7.2 Caso de uso diseño detallado de métodos de clase.…………………….. 3.7.3 Caso de uso generación de código en Java………….………………….. 3.7.4 Caso de uso generación de código de las clases en Java……………….. 3.7.5 Caso de uso para la generación de código detallado de métodos………. 3.8 Arquitectura de SOODA………………………………………………… 3.9 Clases del documento vista……………………………………………… 3.10 Clases para el manejo de gráficos de SOODA..………………………… 3.11 Clases de la arquitectura documento/vista de SOODA………………….. 3.12 Clases en SOODA para la generación de código en Java……………….. 40 40 41 42 43 44 44 45 46 47 48 48 49 48 49 50 52 56 ii 3.13 3.14 3.15 3.16 3.17 3.18 3.19 Clases para construir el diagrama de clases de SOODA ........................... Clases para el manejo de diálogos………….……………………………. Diagrama de secuencias de la captura de datos de las clases……………. Diagrama de secuencias para la creación del diagrama de clases .............. Arquitectura de DDVi……………………..…………………………….. Funcionamiento de DDVi……………………………………………….. Proceso de generación de código para el diseño de fallado……………… 61 62 65 66 68 70 73 Capítulo 4 Pruebas de la herramienta ................................................................... 4.1 Introducción………………………………………………………………. 4.2 Plan de pruebas…………………………………………………………… 4.2.1 Convención de nombres……………………………………………… 4.2.2 Elementos de pruebas………………………………………………… 4.2.3 Características que serán probadas…………………………………… 4.2.4 Características que no se probarán…………………………………… 4.2.5 Enfoque………………………………………………………………. 4.2.6 Criterios de éxito o fracaso…………………………………………… 4.2.6.1 Los criterios de éxito…………………………………………… .. 4.2.6.2 Los criterios de fracaso…………………………………………… 4.2.7 Criterios de la suspensión y requisitos para la reanudación………….. 4.2.8 Entregables de pruebas……………………………………………….. 4.2.9 Tareas de pruebas…………………………………………………….. 4.2.10 Necesidades del entorno……………………………………………… 4.2.11 Riesgos y contingencias……………………………………………… 4.2.12 Aprobaciones………………………………………………………… 4.3 Especificaciones de casos de prueba (CP) ………………………………. 4.4 Especificación de procedimientos de prueba (EP) ………………………. 4.4.1 EP01. Clase Card: Métodos Card() y getNumber()………………….. 4.4.2 EP02. Clase Status: Método toString()………………………………. 4.4.3 EP03. Clase ReceiptPrinter: Método PrintReceipt()…………………. 4.5 Reporte de incidentes de pruebas (RI) …………………………………… 4.6 Reporte de resumen de pruebas (RR) ……………………………………. 4.7 Conclusiones……………………………………………………………… 76 76 77 77 77 78 78 78 79 79 79 79 79 79 80 80 80 80 83 83 89 93 97 98 98 Capítulo 5 Resultados y conclusiones ................................................................... 99 5.1. Introducción……………………………………………………………… 99 5.2. Conclusiones…………………………………………………………….. 100 iii 5.2.1. Beneficios obtenidos…………………………………………………. 100 5.2.2. Limitaciones…………………………………………………………. 101 5.3. Trabajos futuros………………………………………………………….. 101 Anexos…………………………………………………………………………….. .... 102 Anexo A. La MFC y Windows……………………………………………………..... 103 Anexo B. Jerarquía de clases de la MFC…………………………………………….. 108 Referencias bibliográficas………………………………………………………….. 120 iv Índice de Figuras Figura Figura 2.1 Dependencia Figura 2.2 Asociación Figura 2.3 Generalización Figura 2.4 Realización Figura 2.5 Jerarquía en diagramas de Warnier Figura 2.6 Iteración en diagramas de Warnier Figura 2.7 Selección en diagramas de Warnier Figura 2.8 Diagramas de Warnier Página 33 33 34 34 35 35 36 37 Figura 3.1 Estructura general de la aplicación 42 Figura 3.2 Visión global del sistema 43 Figura 3.3 Diagrama de flujo de la metodología propuesta 44 Figura 3.4 Diagrama de flujo del diseño detallado de los métodos 45 Figura 3.5 Diagrama de casos de usos del sistema 46 Figura 3.6 Esquema para la generación de código en Java 48 Figura 3.7 Esquema de la relación documento-vista 49 Figura 3.8 Clases para el manejo de gráficos de SOODA 50 Figura 3.9 Jerarquía de clases del documento/vista de SOODA 54 Figura 3.10 Clases de SOODA para la generación de código en Java 56 Figura 3.11 Clases de SOODA para la construcción de los diagramas de clases 61 Figura 3.12 Clases para el manejo de los recursos de diálogos 63 Figura 3.13 Diagrama de secuencias para capturar los datos de las clases 66 Figura 3.14 Diagrama de secuencias para la creación del diagrama de clases 68 Figura 3.15 Jerarquía de clases del documento/vista de DDVi 70 Figura 3.16 Diagrama de secuencias para la creación del diseño de los métodos 72 v Figura 4.1 Casos de uso del caso de estudio: Cajero automático Figura 4.2 Diagrama de clases del cajero automático Figura 4.3 Código de la clase Card obtenido de [24] Figura 4.4 Cuadro de diálogo para llamar a DDVi Figura 4.5 Diseño del método getNumber() con DDVi Figura 4.6 Modelado y generación de código de la clase Card y sus métodos Card() y getNumber() Figura 4.7 Revisión de la sintaxis con JCreator Figura 4.8 Cuadro de diálogo para la creación de la clase principal de Java Figura 4.9 Revisión de la sintaxis con JCreator Figura 4.10 Ejecución del código con JCreator Figura 4.11 Código de la clase Status obtenido de [24] Figura 4.12 Cuadro de diálogo para llamar a DDVi Figura 4.13 Diseño del método toString() con DDVi Figura 4.14 Modelado y generación de código de la clase Status y su método toString() Figura 4.15 Revisión de la sintaxis con JCreator Figura 4.16 Código de la clase ReceiptPrinter obtenido de [24] Figura 4.17 Cuadro de diálogo para llamar a DDVi Figura 4.18 Diseño del método printReceipt() con DDVi Figura 4.19 Modelado y generación de código de la clase ReceiptPrinter y su método PrintReceipt() Figura 4.20 Revisión de la sintaxis con JCreator 81 82 84 85 85 Figura B1. Jerarquía de clases de la MFC Figura B2. Arquitectura de una aplicación Figura B3. Arquitectura de un objeto aplicación Figura B4. Arquitectura de una plantilla de documento Figura B5. Arquitectura de la clase documento Figura B6. Arquitectura para el soporte de ventanas Figura B7. Arquitectura para el soporte de ventanas marco Figura B8. Arquitectura de las clases vista Figura B9. Arquitectura de las clases diálogo Figura B10. Algunos controles Figura B11. Arquitectura para el soporte de gráficos Figura B12. Arquitectura para el soporte del contexto de dispositivo Figura B13. Objetos de dibujo de gráficos Figura B14. Arquitectura para el soporte de colecciones Figura B15. Clases para el soporte de plantillas de colecciones Figura B16. Jerarquía de clases de la MFC 122 110 111 111 112 113 114 115 115 116 116 117 117 118 118 119 86 87 87 88 89 90 91 91 92 93 94 95 95 96 97 vi 7 Índice de Tablas Tabla Página Tabla 1.1 Herramientas CASE que generan código a partir del modelo orientado a objetos 15 Tabla 2.1 Patrones de diseño orientados a objetos 22 Tabla 2.2 Relación entre las áreas, vistas y diagramas del UML 32 Tabla 4.1 Casos de prueba definidos para la herramienta SOODA y DDVi 83 vii Anexos _______________________________________________________________ 102