martes, 22 de marzo de 2011

Ejemplos de diagramas UML, interfaces gráficas de usuario, y usos del UML en la ingeniería inversa (segunda parte ))

Diagramas uml


La mejor forma de desarrollar un buen diagrama de caso de uso es mediante entrevista directa con los usuarios o posibles futuros usuarios del sistema, poniendo atención a cada una de las actividades o pasos que se van a ir desarrollando desde un primer momento hasta un momento final.

La elaboración de diagramas de uso ayuda poderosamente a un analista a comprender la forma en que un sistema deberá comportarse, obteniendo los requerimientos desde el punto de vista del usuario.

En todo caso de uso siempre hay un actor, que es quien inicia, y luego otro actor (que puede ser el mismo que inicia el caso de uso o puede ser otro diferente), que recibirá algo por parte del sistema. La representación gráfica es directa, de la siguiente forma:



En la figura anterior, la elipse representa el caso de uso. Las dos figuras en los extremos izquierdo y derecho son los actores que intervienen. El actor que inicia se encuentra a la izquierda del caso de uso, y el que recibe a la derecha. El nombre del actor aparece justo debajo de él, y el nombre del caso de uso aparece ya sea dentro de la elipse o justo debajo de ella. Una línea asociativa conecta a un actor con el caso de uso, y representa la comunicación entre el actor y el caso de uso. La línea asociativa es sólida. El rectángulo envuelve a los casos de uso dentro del sistema.

A continuación se muestra un caso de uso que aunque en primera instancia podría parecer complejo, realmente no lo es una vez se comprende el significado de cada uno de los símbolos utilizados, los cuales se explicarán posteriormente uno a uno:






Ya se explicó anteriormente lo que significan la elipse, las figuras de los actores en los extremos izquierdo y derecho, el nombre de los actores debajo de dichas figuras de los extremos, el nombre del caso de uso dentro de las elipses, así como las líneas asociativas y el rectángulo dentro del cual aparecen todos los casos de uso, con el nombre del sistema en la parte superior y siempre dentro del rectángulo.

En el diagrama de ejemplo, un aspecto importante que se ha utilizado es la "inclusión", que permite volver a utilizar los pasos de un caso de uso dentro de otro. Esto significa según el ejemplo mostrado, que tanto "Reabastecer" como "Recolectar dinero" son casos de uso que incluyen siempre otro conjunto de pasos que son los correspondientes a "Exhibir el interior" y "Cubrir el interior". Esto es así porque siempre que se quiera "Reabastecer" una máquina de gaseosas o "Recolectar dinero" contenido en la máquina, inevitablemente se iniciará mediante la apertura de la máquina y se finalizará con el cierre y sellado de la misma.

Se han utilizado líneas discontinuas con una punta de flecha que se dirige hacia las clases dependientes ("Exhibir el interior" y "Cubrir el interior" son las dos clases dependientes). Este tipo de flechas son el símbolo que representa inclusión en la nomenclatura UML. Justo sobre la línea se ha agregado una palabra que se utiliza para revelar la relación de inclusión existente entre los casos de uso vinculados. Esta palabra debe ponerse precisamente sobre la flecha (o a un lado de la línea, si esta fuera vertical, o incluso debajo de la línea si el espacio de trabajo obliga a ello) y debe ser bordeada por dos pares de paréntesis angulares. La palabra que se ha utilizado es «incluir».

En el ejemplo también se ha utilizado la "extensión", que consiste en añadir un nuevo caso de uso al caso original, que sería el caso de uso "base". Para el ejemplo concreto que se ha mostrado, en lugar de sólo reabastecer la máquina de gaseosas con marcas y sabores aleatorios, el reabastecimiento se hace de tal manera que la máquina tenga la misma cantidad de latas para cada una de las marcas y sabores. Pero se debe tener en cuenta que la extensión sólo se puede realizar en puntos indicados de manera específica dentro de la secuencia del caso de uso base. A estos puntos se les conoce como "puntos de extensión." En el caso de uso "Reabastecer," los nuevos pasos (anotar las ventas y abastecer de manera acorde) se darían luego que el representante haya abierto la máquina y esté listo para llenar los compartimientos de las marcas de gaseosas. En este ejemplo, el punto de extensión es "Llenar los compartimientos." Nótese también que para realizar la inclusión, se ha usado una línea de dependencia (línea discontinua con una punta de flecha), junto con la palabra "extender" entre paréntesis angulares. Pero es importante destacar la dirección que tiene la línea de dependencia, pues siempre deben ir dirigidas hacia las clases dependientes. Para el ejemplo, el caso de uso dependiente es "Reabastecer", y el caso de uso independiente es "Reabastecer de acuerdo a las ventas", pues lo primero que se tiene que hacer es verificar cuántas latas de gaseosa hay en existencia para cada marca y sabor según las ventas que se hayan hecho, y luego partiendo de eso se procede a reabastecer con una proporción adecuada. En síntesis, la línea discontinua con una flecha denota una "relación de dependencia", donde el sentido de la flecha apunta hacia la clase o caso de uso dependiente, y por lógica donde no se encuentra la flecha es el caso de uso independiente. Dentro de la elipse del caso de uso básico, para el caso de estar utilizando extensión, debe aparecer el nombre del caso de uso y el punto de extensión, en este caso "Reabastecer" y debajo de eso "Punto de extensión llenar los compartimientos", respectivamente.

En el ejemplo también se ha hecho uso de la "generalización". Esto significa que las clases pueden heredarse entre sí. La generalización se modela con líneas continuas y una punta de flecha en forma de triángulo sin rellenar que apunta hacia el caso de uso primario. La relación de generalización puede establecerse entre actores, así como entre casos de uso. Para el ejemplo presentado se ha hecho entre casos de uso, y el significado es que el caso de uso primario es "Comprar gaseosa" (pues hacia ahí apunta la flecha), y el caso de uso secundario es "Comprar un vaso de gaseosa". Entonces el caso de uso secundario hereda o tiene acciones del caso de uso primario, tales como "agregar hielo", etc. El caso secundario hereda las acciones del primario, pero además agrega sus propias acciones. Por tanto, se puede aplicar el caso de uso secundario en cualquier lugar donde aplique el primario.


Ejemplo de diagrama de estados


Conforme un sistema interactúa con los usuarios y (posiblemente) con otros sistemas, los objetos que lo conforman pasan por cambios necesarios para ajustar las interacciones. Por esa razón se necesita contar con un mecanismo para cambios en el modelo. Un cambio en un sistema se da debido a que los objetos que componen dicho sistema modificaron su estado como respuesta a los sucesos y al tiempo. Un diagrama de estados también se conoce como un "motor de estado."



El ícono para el estado, como se aprecia en la Figura 3, es un rectángulo de vértices redondeados, y el símbolo de una transición es una línea continua y una punta de flecha. El círculo relleno se interpreta como el punto inicial de una secuencia de estados, y la diana representa al punto final.

Se puede subdividir el símbolo de la Figura 3 en áreas que muestren el nombre, variables y actividades del estado, de esta forma:



Las variables de estado como cronómetros o contadores son, en ocasiones, de ayuda. Las actividades constan de sucesos y acciones: tres de las más utilizadas son entrada (qué sucede cuando el sistema entra al estado), salida (qué sucede cuando el sistema sale del estado), y hacer (qué sucede cuando el sistema está en el estado). Se pueden agregar otros conforme sea necesario.

A continuación se muestra un ejemplo concreto de un diagrama de estados:



Como se puede ver en la Figura 5, lo primero que se hace es encender la máquina de fax, con lo cual esta arranca y se encuentra lista en condiciones normales, para realizar el envío de fax, que es el siguiente estado registrado. Cuando se envía un fax –esto es, cuando se encuentra en estado de envío de fax- la máquina de fax anota la fecha y hora en que inició el envío (los valores de las variables de estado "fecha" y "hora"), y también anota el número telefónico así como el nombre del propietario (los valores de las variables de estado "teléfono" y "propietario"). Al encontrarse en este estado, la máquina se encarga de agregar un registro de fecha y hora al fax, número telefónico y nombre del propietario. En otras actividades de este estado, la máquina jalará las hojas, paginará el fax y finalizará la transmisión. Mientras se encuentre en el estado de inactividad, la máquina de fax mostrará la fecha y la hora en una pantalla. Finalmente, cuando ya no se vaya a utilizar la máquina de fax por un periodo determinado, se podrá apagar, siendo este también un estado concreto.


Ejemplo de diagrama de secuencias



Este tipo de diagramas muestra una interacción ordenada según la secuencia de eventos vista a la luz de una línea de tiempo. En particular, se muestran los objetos participantes en la interacción y los mensajes que intercambian ordenados según su secuencia en el tiempo.

El eje vertical representa el tiempo, y en el eje horizontal se colocan los objetos y actores participantes en la interacción, sin un orden prefijado, aunque por orden lo usual es colocar los objetos de izquierda a derecha y en la parte superior. Cada objeto o actor tiene una línea vertical, y los mensajes se representan mediante flechas entre los distintos objetos. El tiempo fluye de arriba hacia abajo. Se pueden colocar etiquetas (como restricciones de tiempo, descripciones de acciones, etc.) bien en el margen izquierdo o bien junto a las transiciones o activaciones a las que se refieren. Cada línea de vida de un objeto es una línea discontinua que se desplaza hacia abajo del objeto. Una línea continua con una punta de flecha conecta a una línea de vida con otra, y representa un mensaje de un objeto a otro. El tiempo se inicia en la parte superior y continúa hacia abajo. Aunque un actor es el que normalmente inicia la secuencia, su símbolo no es parte del conjunto de símbolos del diagrama de secuencias. No necesariamente se debe especificar el tiempo de manera explícita (como en segundos, minutos, horas, días, etc.), aunque se puede hacer si resulta necesario o conveniente. En todo caso lo que siempre se tiene que hacer es ubicar correctamente en el eje vertical la secuencia correcta de eventos que se deben ir dando de forma cronológica o en una línea de tiempo.

El siguiente ejemplo muestra cómo se puede realizar un diagrama de secuencias:





En la Figura 6 se representa la forma en que la GUI interacciona con otros objetos. Obsérvese que la secuencia se origina y finaliza en el estado operativo de la GUI, como es de esperar, pero para llegar a eso se da una secuencia de procesos plasmados en el diagrama.





Ejemplo de diagrama de colaboraciones



   




En este tipo de diagramas se muestra una interacción organizada, basándose en los objetos que toman parte en la interacción y los enlaces entre los mismos (en cuanto a la interacción se refiere). A diferencia de los diagramas de secuencia, los diagramas de colaboración muestran las relaciones entre los roles de los objetos. La secuencia de los mensajes y los flujos de ejecución concurrentes deben determinarse explícitamente mediante números de secuencia. Aunque se muestran los mensajes que se envían los objetos entre sí, por lo general se evita la multiplicidad de mensajes dado que podría ser fuente de confusión. En la representación de los mensajes, la flecha que se dibuja cerca de la línea de asociación entre dos objetos, apunta al objeto receptor. El mensaje finaliza con un par de paréntesis, dentro de los cuales se colocan los parámetros (en caso de haber alguno) con los que funcionará la operación.



Se puede convertir cualquier diagrama de secuencias en diagrama de colaboraciones y viceversa. Por medio de esto se puede representar la información de secuencia en un diagrama de colaboraciones. Para ello se agrega una cifra a la etiqueta de un mensaje, la cual corresponde a la secuencia propia del mensaje. La cifra y el mensaje se separan mediante dos puntos (:).

El ejemplo de diagrama de secuencias mostrado en la Figura 6, se convertirá ahora a un diagrama de colaboraciones, quedando de la siguiente manera:



Las colaboraciones representadas en la Figura 8 se dan de esta manera:

  • 1. La GUI notifica al sistema operativo que se oprimió una tecla.
  • 2. El sistema operativo le notifica a la CPU.
  • 3. El sistema operativo actualiza la GUI. 
  • 4. La CPU notifica a la tarjeta de vídeo.
  • 5. La tarjeta de vídeo envía un mensaje al monitor. 
  • 6. El monitor presenta el carácter alfanumérico en la pantalla, con lo que se hará evidente al usuario. 



Ejemplo de diagrama de actividades


Este tipo de diagrama le resulta familiar a la mayoría de programadores, pues en cualquier curso básico de programación se comienza por trabajar con los diagramas de flujo para conocer la lógica que llevará un programa. Los tradicionales diagramas de flujo muestran una secuencia de pasos, procesos, puntos de decisión y bifurcaciones. Con sus diversas características y tipos de diagramas, el UML se podría decir que es en cierta medida, un diagrama de flujo robustecido o reforzado. Para el caso particular del diagrama de actividades, es muy parecido a los viejos diagramas de flujo, pues muestra los pasos (conocidos como actividades) así como puntos de decisión y bifurcaciones. Lo que hacen es mostrar una visión simplificada de lo que ocurre durante una operación o proceso. Se puede decir también que es una extensión del diagrama de estados. El diagrama de estados muestra los estados de un objeto y representa las actividades como flechas que conectan a los estados. Por su parte, el diagrama de actividades resalta, precisamente, las actividades.

Cada actividad se representa por un rectángulo con las esquinas redondeadas (más angosto y ovalado que la representación del estado). El procesamiento dentro de una actividad se lleva a cabo y, al realizarse, se continúa con la siguiente actividad. Una flecha representa la transición de una a otra actividad. Al igual que el diagrama de estados, el de actividad cuenta con un punto inicial (representado por un círculo relleno) y uno final (representado por una diana).



Los diagramas de actividades tienen la poderosa herramienta de permitir tomar decisiones, como se muestra en la siguiente figura:






Es posible también modelar actividades que serán ejecutadas al mismo tiempo (es decir, de forma concurrente) y que luego se reúnan. Para representar esto, se utiliza una línea gruesa perpendicular a la transición y las rutas parten de ella. Para representar la reincorporación, ambas rutas apuntan a otra línea gruesa, de esta forma:



Se muestra ahora un ejemplo en el que se utilizará un diagrama de actividades para utilizar una aplicación de oficina (software) para crear un documento. La secuencia sería la siguiente:

  • 1. Abrir la aplicación para procesamiento de textos.
  • 2. Crear un archivo con un nombre único en una carpeta.
  • 3. Guardar el archivo con un nombre único en una carpeta.
  • 4. Teclear el documento.
  • 5. Si se necesitan ilustraciones, se abre la aplicación relacionada, se generan los gráficos y se colocan en el documento.
  • 6. Si se necesita una hoja de cálculo, se abre la aplicación relacionada, se crea la hoja correspondiente y se coloca en el documento.
  • 7. Se guarda el archivo.
  • 8. Se imprime el documento
  • 9. Se sale de la aplicación de oficina.


El diagrama de actividades queda representado así:







  • Ejemplo de diagrama de componentes



Un componente de software es una parte física de un sistema, y se encuentra en la computadora, no en la mente del analista. Ejemplos de componentes son tablas, archivos de datos, ejecutables, bibliotecas de vínculos dinámicos, documentos y cosas por el estilo.

Lo que contiene un diagrama de componentes es lógicamente componentes, interfaces y relaciones, aunque también pueden aparecer otros tipos de símbolos vistos anteriormente.

El símbolo principal de un diagrama de componentes es un rectángulo que tiene otros dos sobrepuestos en su lado izquierdo, con el nombre del componente dentro del rectángulo más grande, como se muestra en la siguiente figura:





Como ejemplo se presenta el siguiente diagrama de componentes para una página web con componentes ActiveX:





Como se observa en el ejemplo, existe un conjunto de componentes que se encuentran interrelacionados utilizando flechas discontinuas que como se explicó anteriormente en los diagramas de casos de uso, representan relaciones de dependencia, donde la dirección de la flecha apunta a la clase dependiente, que en este caso sería el componente dependiente, y por consecuencia en el extremo donde no hay flecha se encuentra el componente independiente. Se ha hecho uso también de un símbolo que no se había utilizado antes, que es el símbolo de anotación y que sirve para hacer precisamente anotaciones o comentarios:



Ejemplo de diagrama de distribución


Este tipo de diagramas se enfoca específicamente al hardware de un sistema determinado.

El elemento primordial del hardware es un nodo, que es un nombre genérico para todo tipo de recurso de cómputo.

Para comenzar, se debe saber que un nodo se representa mediante un cubo:



Dentro del cubo se puede introducir información sobre el nodo, que puede ser simplemente texto o inclusive componentes, usando los diagramas de componentes anteriormente ejemplificados. En el ejemplo que se muestra a continuación, puede verse un nodo que tiene componentes de software (Windows, Office e Internet Explorer). Aunque como ya se dijo, los diagramas de distribución se enfocan en la parte de hardware, cada uno de los nodos puede contener otros componentes, incluyendo software, lo cual puede ser especificado en el diagrama:




Ejemplo de diagrama de clases


En UML, un rectángulo es el símbolo que representa a la clase, y se divide en tres áreas. El área superior contiene el nombre de la clase, el área central contiene los atributos o propiedades, y el área inferior, las acciones, procedimientos, métodos o funciones. Un diagrama de clases está formado por varios rectángulos de este tipo conectados por líneas que muestran la manera en que las clases se relacionan entre sí.

En el ejemplo que se presentará a continuación, se muestran tres clases, donde las líneas continuas con extremos en forma de triángulo sin rellenar, tal como se había explicado anteriormente en este documento, son los símbolos de asociación de generalización, que sirven para mostrar herencia de una clase a otra, donde el extremo del triángulo sin rellenar (que simula una flecha) apunta hacia la clase base, y en el extremo de la línea continua que no tiene dicho triángulo se encuentra la clase que hereda. Para decirlo de forma más concreta y de acuerdo al ejemplo, la clase base es "Vehículo" y las clases que heredan las propiedades y acciones de la clase "Vehículo" son "Auto" y "Camioneta", lo cual al imaginarlo en un escenario de la vida real, es completamente atinado y razonable.





Ejemplo de diagrama de objetos


Partiendo del hecho que un objeto es una instancia de clase, tal como se define en la conceptualización básica de la programación orientada a objetos, en UML la representación de un diagrama de objetos se hace de tal forma que teniendo ya una clase, el símbolo del objeto es un rectángulo, pero con el nombre subrayado. El nombre de la instancia específica se encuentra a la izquierda de los dos puntos (:), y el nombre de la clase a la derecha. Por ejemplo, si ya se tuviera una clase llamada "Lavadora", una instancia de esa clase o un objeto instanciado a partir de esa clase se representaría de la siguiente forma:





  • CAPITULO 2



Interfaz gráfica de usuario, su importancia y elementos típicos que la componen
Definición de interfaz gráfica de usuario

La interfaz gráfica de usuario, que muchas veces es referida como GUI por sus siglas en inglés (Graphical User Interface), es un tipo de interfaz de usuario que se caracteriza y diferencia por el hecho de utilizar un conjunto de imágenes y objetos gráficos para representar la información y acciones disponibles en la interfaz.

Actualmente todos o la gran mayoría de sistemas operativos cuentan con una interfaz gráfica de usuario. Anteriormente solamente se contaba con acceso a línea de comandos, desde donde se utilizaban instrucciones o comandos para realizar determinados procesos.

Ejemplos típicos de interfaz gráfica de usuario son el escritorio del sistema operativo Windows, el entorno X-Window de Linux, en entorno Aqua de Mac OS X, etc.

Elementos de una interfaz gráfica de usuario

No todos las interfaces gráficas de usuario tienen los mismos elementos, pero típicamente tienen componentes tales como:

Cuadros de diálogo: es una pequeña ventana que se utiliza para abrir un diálogo con el usuario para intercambiar información.



Figura 20. Cuadro de diálogo.

Menús: sirven para desplegar un conjunto de opciones disponibles en un programa o aplicación.



Figura 21. Menús.

Pestañas de propiedades: dan acceso a un conjunto de propiedades o configuraciones ordenadas por secciones:



Figura 22. Pestañas de propiedades.

Barras de herramientas: presentan opciones de fácil acceso, que aunque usualmente también se encuentran disponibles en las opciones de menú o mediante combinaciones de teclas, las barras de herramientas ofrecen las principales funcionalidades de formato y otras opciones, de forma fácil y accesible a un solo clic o a un par de clics de distancia:



Figura 23. Barras de herramientas.

Asistentes: son ventanas sucesivas que van guiando a un usuario en la realización de un proceso, como la instalación o desinstalación de un programa por ejemplo.





Figura 24. Asistente de desinstalación.

Ventanas: son áreas visuales, normalmente de forma rectangular, que contienen algún tipo de interfaz de usuario, mostrando la salida y permitiendo la entrada de datos para realizar determinados procesos. Se utilizan en las interfaces gráficas de usuario y pueden ser manipuladas con un puntero.



Figura 25. Ventanas en una interfaz gráfica de usuario.

Entorno de escritorio: es una solución completa de interfaz gráfica de usuario, que provee al usuario elementos tales como íconos, barras de herramientas, aplicaciones e integración entre aplicaciones con posibilidades de realizar acciones como arrastrar y soltar. En general todo esto proporciona un manejo amigable y fácil del sistema operativo.



Figura 26. Entorno de escritorio Mac OS X.

Importancia de las interfaces gráficas de usuario en los sistemas

Si bien es cierto que muchos expertos están acostumbrados a trabajar desde una consola haciendo uso de comandos (por ejemplo muchos usuarios avanzados de Linux), eso no es de ninguna manera argumento para restar valor o importancia a las interfaces gráficas de usuario. Se debe considerar que los sistemas casi siempre van enfocados a tener algún tipo de interacción con usuarios finales, y éstos aprecian y además esperan que se les proporcionen sistemas con interfaces gráficas de calidad, amenas o amigables y fáciles de usar.

La importancia de las GUI es evidente al considerar que los sistemas interactúan con usuarios finales y aún cuando no lo hicieran, incluso usuarios avanzados o expertos no tendrían problema en tener al frente una interfaz gráfica de calidad y que permita realizar todas las operaciones que se requieran de manera rápida, eficiente, llamativa y amigable.

Además, cuando se trata de vender un producto (o un sistema), la vista es uno de los sentidos más poderosos para capturar la atención. Un ambiente gráfico de calidad puede atraer más usuarios o hacer que los productos o sistemas se vendan en mayor cantidad o a un mayor precio. Además de los efectos o aspectos visuales, las GUI incorporan usualmente sonidos y movimientos, es decir efectos multimedia que provocan una excelente impresión en los usuarios y ofrecen ventajas y beneficios indiscutibles.

  • CAPÍTULO 3


Ingeniería inversa y su relación con los diagramas UML
Definición de ingeniería inversa

La ingeniería inversa es el proceso de descubrir los principios tecnológicos de un dispositivo, objeto o sistema a través del análisis de su estructura, función y operación. Esto significa a menudo tomar algo (por ejemplo un dispositivo mecánico, componente electrónico, o programa de software) y analizarlo en detalle, desde las partes físicas que lo componen hasta otro tipo de detalles que involucran su funcionamiento, etc. Lo que se busca con esto es crear un nuevo dispositivo o sistema que haga lo mismo, copiando cualquier cosa del recurso o sistema original.

Relación entre la ingeniería inversa y los diagramas UML

Los diagramas UML pueden ser una poderosa herramienta para hacer uso de la ingeniería inversa. Sin usar diagramas UML, se corre el riesgo de aplicar la ingeniería inversa de forma desordenada y empírica, encontrando algunas soluciones pero no documentándolas y dándolas a conocer correctamente.

Al utilizar diagramas UML en la ingeniería inversa, se puede determinar paso a paso el funcionamiento de un sistema, pero además de eso, al mismo tiempo se documenta ordenadamente cada una de las conclusiones que se van obteniendo.

Por ejemplo, utilizar un diagrama de caso de uso aplicado al funcionamiento de un sistema, permitirá obtener importantes conclusiones iniciales respecto al funcionamiento de un sistema. Posteriormente se podría aplicar un diagrama de estados de acuerdo al funcionamiento que se observe en un determinado sistema. Así sucesivamente de acuerdo a las necesidades específicas al momento de aplicar la ingeniería inversa, se pueden ir aplicando diagramas UML que luego se pueden unificar y generar una idea global, completa y al mismo tiempo detallada sobre los pasos y procesos que se dan en el funcionamiento de un sistema, para poderlo reproducir y obtener los resultados esperados.

Conclusión

Luego de estudiar cada uno de los diagramas de UML, así como su utilidad para proyectos de ingeniería inversa y para muchos otros tipos de sistemas, se puede concluir que aunque no es la única herramienta para el análisis y diseño de sistemas, sí es una opción muy poderosa que puede ofrecer excelentes soluciones y una gran ayuda a la hora de crear o diseñar un sistema. Esto también ayuda a trabajar ordenadamente, ahorrando tiempo, dinero y muchos problemas que se podrían desencadenar como consecuencia de no tener una adecuada y correcta documentación de las partes que componen un sistema.

Igualmente se ha ofrecido un breve y conciso enfoque en las interfaces gráficas de usuario, que son prácticamente indispensables en los sistemas informáticos modernos, así como también en otros sistemas que aunque no están directamente orientados a la informática, hacen uso de ella al menos indirectamente.

Por supuesto que este documento explica cada uno de los temas expuestos de manera breve, pero la idea que se da es suficiente como para presentar un buen panorama de lo que es el UML y los usos que tiene, así como de los elementos que componen una interfaz gráfica de usuario.

Ejemplos de diagramas UML, interfaces gráficas de usuario, y usos del UML en la ingeniería inversa

Introducción


 El éxito de un proyecto depende en gran medida de un buen plan y de una buena organización. En vista de ello, se hace necesario contar con herramientas eficientes para desarrollar sistemas.

La utilización del UML como herramienta de diseño de sistemas no se trata de una aventura sin precedentes, sino por el contrario, UML es actualmente un estándar que ha llegado a hacerse popular por la aceptación que ha tenido y la efectividad que ha representado para muchos analistas y diseñadores de sistemas.

En este documento se muestra de manera general cada uno de los diagramas utilizados en UML, explicados de manera tal que incluso una persona que nunca haya escuchado hablar de UML, tendrá una visión general y útil sobre esta herramienta luego de leer este documento.

Además de los diagramas UML ejemplificados concretamente uno a uno, también se habla en el Capítulo 2 sobre el famoso GUI (Graphical User Interface). En el Capítulo 3 se explica cómo el uso y aplicación del UML puede ser de gran ayuda a la hora de trabajar en un proyecto de ingeniería inversa.



Objetivos



Objetivo general


"ejemplificar claramente cada uno de los diagramas UML para el diseño eficiente de sistemas."




Objetivos específicos




Mostrar los beneficios que ofrece cada uno de los diagramas UML a la hora de diseñar sistemas.

Ofrecer un panorama claro de los usos prácticos del UML.

Explicar los elementos principales de una interfaz gráfica de usuario, sus beneficios y usos en los sistemas informáticos actuales.

Dar a conocer cómo los diagramas UML pueden ser fundamentales a la hora de realizar proyectos de ingeniería inversa.









Justificación



Debido a que muchos analistas de sistemas no utilizan un método ordenado y sistemático para el análisis y diseño de sus proyectos, la elaboración de este documento se justifica ante la necesidad de conocer esta popular y globalmente aceptada herramienta conocida como UML, que permite desarrollar sistemas metódicamente y paso a paso, documentando gráficamente mediante diagramas lo que se podría conocer como "el plano del sistema", si se hiciera la analogía con los planos a la hora de construir un edificio. Por esa razón, conocer sobre el UML y sus usos se hace necesario y fundamental para todo analista de sistemas. De la misma forma, sabiendo que los sistemas modernos hacen uso de programas de software con interfaces gráficas de calidad, resulta también necesario dar a conocer de manera general lo que son las interfaces gráficas de usuario y las partes o elementos que las componen.





CAPÍTULO 1

Ejemplos de cada uno de los diagramas UML
UML es el Lenguaje Unificado de Modelado (Unified Modeling Language, por sus siglas en inglés). Se trata del lenguaje de diseño y modelado de sistemas más usado y conocido en la actualidad. A continuación se presentan los diagramas utilizados en UML para el 
modelado de sistemas:

Ejemplo de diagrama de caso de uso:

Este tipo de diagramas describe cómo se usa el sistema, partiendo desde el punto de vista del usuario final. Esto da una buena pauta para conocer más a fondo los requisitos que deberá tener el sistema a desarrollar. Debe tenerse el cuidado de no confundir la palabra "cómo", cuando se dice los diagramas de caso de uso describen "cómo se usa el sistema". Esto se refiere al "cómo" desde el punto de vista de los pasos que se van a realizar por parte del usuario final, y no al "cómo" del procedimiento técnico que se va a utilizar para dar solución a un problema o caso específico.

El objetivo de este tipo de diagramas es mostrar la manera en la que un usuario final va a interactuar con el sistema a desarrollar, sin preocuparse por la forma en la que se va a lograr implementar eso, técnicamente hablando, es decir, sin tomar en cuenta los mecanismos que se van a utilizar para crear o hacer funcionar el sistema.

martes, 8 de marzo de 2011

POO ( programación orientada a objetos )

  • ·         POO


La programación orientada a objetos o POO (OOP según sus siglas en inglés) es un paradigma de programación que usa objetos y sus interacciones, para diseñar aplicaciones y programas informáticos. Está basado en varias técnicas, incluyendo herencia, abstracción, polimorfismo y encapsulamiento. Su uso se popularizó a principios de la década de los años 1990. En la actualidad, existe variedad de lenguajes de programación que soportan la orientación a objetos.


  • ·         Clases de objetos e instancias


Una clase es la estructura de un objeto, es decir, la definición de todos los elementos de que está hecho un objeto. Un objeto es, por lo tanto, el "resultado" de una clase. En realidad, un objeto es una instancia de una clase, por lo que se pueden intercambiar los términos objeto o instancia (o incluso evento).
Una clase se compone de dos partes:
Atributos (denominados, por lo general, datos miembros): esto es, los datos que se refieren al estado del objeto
Métodos (denominados, por lo general, funciones miembros): son funciones que pueden aplicarse a objetos
Si tenemos una clase llamada auto, los objetos Peugeot y Renault serán instancias de esa clase. También puede haber otros objetos Peugeot 406, diferenciados por su número de modelo. Asimismo, dos instancias de una clase pueden tener los mismos atributos, pero considerarse objetos distintos independientes. En un contexto real: dos camisas pueden ser idénticas, pero no obstante, también ser diferentes de alguna manera. Sin embargo, si las mezclamos es imposible distinguir una de la otra.


  • ·         El concepto de objeto



La programación orientada a objetos consiste en ordenar datos en conjuntos modulares de elementos de información del mundo real (denominado un dominio). Estos elementos de datos se llaman objetos. Estos datos se agrupan de acuerdo a las características principales del mundo real de estos elementos (tamaño, color, etc.).

El enfoque de objetos es una idea que se ha probado con creces. Simula fue el primer lenguaje de programación en implementar el concepto de clases en 1967. En 1976, Smalltalk implementó los conceptos de encapsulación, agrupación y herencia (los conceptos principales de la programación orientada a objetos). Por otra parte, se han implementado varios lenguajes de programación orientada a objetos a escala global (Eiffel, Objective C, Loops, etc.).

La dificultad que presenta este enfoque es la creación de una representación abstracta, en forma de objetos, de entidades que realmente existen (perro, auto, lámpara eléctrica...) o que existen virtualmente (seguridad social, clima...).

Un objeto se caracteriza por varios conceptos:

Atributos: estos son los datos que caracterizan al objeto. Son variables que almacenan datos relacionados al estado de un objeto.
Métodos (usualmente llamados funciones de miembro): Los métodos de un objeto caracterizan su comportamiento, es decir, son todas las acciones (denominadas operaciones) que el objeto puede realizar por sí mismo. Estas operaciones hacen posible que el objeto responda a las solicitudes externas (o que actúe sobre otros objetos). Además, las operaciones están estrechamente ligadas a los atributos, ya que sus acciones pueden depender de, o modificar, los valores de un atributo.
Identidad: El objeto tiene una identidad, que lo distingue de otros objetos, sin considerar su estado. Por lo general, esta identidad se crea mediante un identificador que deriva naturalmente de un problema (por ejemplo: un producto puede estar representado por un código, un automóvil, por un número de modelo, etc.).




  • ·         El concepto de herencia poo



La herencia es específica de la programación orientada a objetos, donde una clase nueva se crea a partir de una clase existente. La herencia (a la que habitualmente se denomina subclases) proviene del hecho de que la subclase (la nueva clase creada) contiene las atributos y métodos de la clase primaria. La principal ventaja de la herencia es la capacidad para definir atributos y métodos nuevos para la subclase, que luego se aplican a los atributos y métodos heredados.
Esta particularidad permite crear una estructura jerárquica de clases cada vez más especializada. La gran ventaja es que uno ya no debe comenzar desde cero cuando desea especializar una clase existente. Como resultado, se pueden adquirir bibliotecas de clases que ofrecen una base que puede especializarse a voluntad (la compañía que vende estas clases tiende a proteger las datos miembro usando la
  • ·         Jerarquía de clase poo

La relación primaria-secundaria entre clases puede representarse desde un punto de vista jerárquico, denominado vista de clases en árbol. La vista en árbol comienza con una clase general llamada superclase (a la que algunas veces se hace referencia como clase primaria, clase padre, clase principal, o clase madre; existen muchas metáforas genealógicas). Las clases derivadas (clase secundaria o subclase) se vuelven cada vez más especializadas a medida que van descendiendo el árbol. Por lo tanto, se suele hacer referencia a la relación que une a una clase secundaria con una clase primaria mediante la frase "es una" x o y.
Descripción: Jerarquía de clase



  • ·         Herrencia multiple


Algunos lenguajes orientados a objetos, como C++ permiten herencias múltiples, lo que significa que una clase puede heredar los atributos de otras dos superclases. Este método puede utilizarse para agrupar atributos y métodos desde varias clases dentro de una sola.

Descripción: Herencia múltiple


  • Definición de polimorfismo



La palabra polimorfismo proviene del griego y significa que posee varias formas diferentes. Este es uno de los conceptos esenciales de una programación orientada a objetos. Así como la herencia está relacionada con las clases y su jerarquía, el polimorfismo se relaciona con los métodos.

En general, hay tres tipos de polimorfismo:

  •          Polimorfismo de sobrecarga
  • ·         Polimorfismo paramétrico (también llamado polimorfismo de plantillas)
  • ·         Polimorfismo de inclusión (también llamado redefinición o subtipado)


Descripción: Los diferentes tipos de polimorfismo
Trataremos de describir ahora con más precisión estos tipos de polimorfismo, pero le sugerimos prestar atención, ya que muchas personas suelen confundirse al tratar de comprender las diferencias existentes entre estos tres tipos.
Polimorfismo de sobrecarga

  • El polimorfismo de sobrecarga


ocurre cuando las funciones del mismo nombre existen, con funcionalidad similar, en clases que son completamente independientes una de otra (éstas no tienen que ser clases secundarias de la clase objeto). Por ejemplo, la clase complex, la clase image y la clase link pueden todas tener la función "display". Esto significa que no necesitamos preocuparnos sobre el tipo de objeto con el que estamos trabajando si todo lo que deseamos es verlo en la pantalla.

Por lo tanto, el polimorfismo de sobrecarga nos permite definir operadores cuyos comportamientos varían de acuerdo a los parámetros que se les aplican. Así es posible, por ejemplo, agregar el operador + y hacer que se comporte de manera distinta cuando está haciendo referencia a una operación entre dos números enteros (suma) o bien cuando se encuentra entre dos cadenas de caracteres (concatenación).

  • Polimorfismo paramétrico


El polimorfismo paramétrico es la capacidad para definir varias funciones utilizando el mismo nombre, pero usando parámetros diferentes (nombre y/o tipo). El polimorfismo paramétrico selecciona automáticamente el método correcto a aplicar en función del tipo de datos pasados en el parámetro.

Por lo tanto, podemos por ejemplo, definir varios métodos homónimos de addition() efectuando una suma de valores.

El método int addition(int,int) devolvería la suma de dos números enteros.
float addition(float, float) devolvería la suma de dos flotantes.
char addition(char, char) daría por resultado la suma de dos caracteres definidos por el autor.
etc.
Una signature es el nombre y tipo (estático) que se da a los argumentos de una función. Por esto, una firma de método determina qué elemento se va a llamar.



  
  • Polomorfismo de subtipado




La habilidad para redefinir un método en clases que se hereda de una clase base se llama especialización. Por lo tanto, se puede llamar un método de objeto sin tener que conocer su tipo intrínseco: esto es polimorfismo de subtipado. Permite no tomar en cuenta detalles de las clases especializadas de una familia de objetos, enmascarándolos con una interfaz común (siendo esta la clase básica).

Imagine un juego de ajedrez con los objetos rey, reina, alfil, caballo, torre y peón, cada uno heredando el objeto pieza.
El método movimiento podría, usando polimorfismo de subtipado, hacer el movimiento correspondiente de acuerdo a la clase objeto que se llama. Esto permite al programa realizar el movimiento.de_pieza sin tener que verse conectado con cada tipo de pieza en particular.




  • ·         ATRIBUTOS



Los atributos son datos específicos de una clase. En la definición de clase se indica cuales son los atributos y conque nombre se va a designar a cada uno de ellos. El que una declaración de atributo sea pública significa que el elemento definido pueda utilizarse libremente desde cualquier otro punto del programa.

En el caso de una clase su carácter público es necesario para poder crear objetos de esa clase en otros puntos del programa (new). Para acceder a un atributo hay que indicarle el nombre del objeto al que pertenece:

unaEntrada.nombre = "Juan Pablo"

unaEntrada.apellidos = "de Frutos Martínez"






  • ·         ENCAPSULADO Y OCULTACIÓN DE OBJETOS




Hay que tener presente que todos los programas en su nivel más simple constan de dos cosas: código y datos. Para tener una idea sobre lo que es el encapsulado, se puede pensar en un envoltorio protector alrededor del código y los datos que se manipulan. El envoltorio, que como se ve protege el código y define el comportamiento, también protege los datos para evitar que otro código acceda a ellos de manera arbitraria. El poder del código encapsulado viene dado por el conocimiento tan extensivo de acceso al mismo y puede ser utilizado de este modo independientemente de los detalles de implementación.

En Java, la base del encapsulado es la clase. Se crea una clase que representa una abstracción para un conjunto de objetos que comparten la misma estructura y comportamiento. Un objeto es una estancia única de una clase que mantiene la estructura y comportamiento de la misma. A estos objetos se les llama instancia de una clase. El comportamiento e interfaz de una clase se definen mediante métodos que operan sobre los datos de una instancia. Un método es un mensaje para realizar alguna acción en un objeto.

A la hora de llevar a cabo el encapsulado existen métodos para ocultar la complejidad de la implementación dentro de una clase. Cada método o variable se puede marcar como público o privado. La interfaz pública representa todo lo que los usuarios externos de la clase necesitan conocer o pueden conocer. Los métodos y datos privados no pueden ser accedidos. Es aconsejable ocultar la mayoría de las variables de una instancia. Esto ayuda a proteger el objeto frente a la manipulación de los datos por métodos ajenos a la clase.

La clase es lo que agrupa los atributos generales de un objeto y los métodos para operar en él. Una instancia es un caso concreto de la clase de un objeto.

Un programa escrito en Java es un conjunto de clases interrelacionadas, cada una de las cuales contienen métodos (funciones) y atributos (datos) propios. Los elementos contenidos en una clase son responsabilidad única y exclusiva de ésta y no pueden ser modificados por ninguna otra. Sin embargo, una de las características principales es que las clases están interrelacionadas, pues son todas partes de un mismo problema y cooperan entre sí para lograr la solución. Para conseguir esta relación sin comprometer la privacidad de sus componentes se crea una interfaz que define los únicos caminos, a través de los cuales puede establecer una comunicación con el resto de las clases. La interfaz será por lo tanto un conjunto de métodos que deberán ser accesibles públicamente para que otras clases puedan utilizarlos.

Para limitar el acceso a las variables internas de una clase, se añade el término private antes de su declaración. Así se limita el acceso desde el exterior. Cuando una variable tiene la característica private, será invisible incluso para las clases que hereden de ésta. Si se quiere mantener la integridad, pero que a la vez esos atributos puedan ser heredados, se utilizará el modificador protected en vez de private.

  • ·         public class EntradaAgenda {·         protected String nombre ;
  • ·         public class EntradaAmigo extends EntradaAgenda {
  • ·         private String apodo;


Así nombre podrá ser heredado en la clase EntradaAmigo, pero continua siendo inaccesible para el resto de las clases.

Para tener la certeza de que todo funciona del modo adecuado, evitar la modificación de los datos es algo necesario y la manera de conseguirlo es haciendo invisibles los datos al exterior.

Como beneficios del encapsulado se obtienen los siguientes:

Las clases se pueden desarrollar de manera independiente: la implementación que se haga de cada una de ellas no influye en el resto de las implementaciones.

Una vez escrita una clase y se comprueba que su funcionamiento es correcto, se tendrá la certeza de que siempre lo será. 


  • ·         Métodos



Son los métodos de una clase son funciones propias de la misma, formando parte de su definición. Cada instancia de la clase contiene los métodos y atributos particulares de la misma. Los métodos de una clase operan sobre los atributos particulares. La llamada de un método es similar a la consulta de atributo: nombre de objeto.método:

unaEntrada.muestraDatos ( );

Los paréntesis son obligatorios para la definición de los métodos aunque no se emplee ningún argumento. Una de las consecuencias de que Java sea un lenguaje orientado a objetos es que todo el código que se escriba ha de estar incluido dentro de una clase.

La creación de un objeto mediante new involucra la invocación de un método especial de la clase denominado constructor, encargado de realizar las funciones de inicialización necesarias para la correcta creación del objeto. El compilador de Java introduce un constructor de forma implícita si el programador no proporciona un constructor propio.

Los lenguajes orientados a objetos, proporcionan mecanismos que refuerzan el modelo orientado a objetos. Los mecanismos fundamentales se llaman encapsulado, herencia y polimorfismo.



  •  ·         ACCESORES



En un capítulo anterior se trató brevemente las variables instancia, pero no se hizo mucho con ellas. Las variables instancia de un objeto son sus atributos, eso que diferencia a un objeto de otro dentro de la misma clase. Es importante poder modificar y leer estos atributos; lo que supone definir métodos denominados //accesores de atributos//. Veremos en un momento que no siempre hay que definir los métodos accesores explícitamente, pero vayamos paso a paso. Los dos tipos de accesores son los de //escritura// y los de //lectura//.
Los accesores permiten el acceso a los atributos del objeto.
:

# SIN accesores

class Cancion
  def initialize(titulo, artista)
    @titulo = titulo
    @artista = artista
  end
  def titulo
    @titulo
  end
  def artista
    @artista
  end
end

cancion = Cancion.new("Brazil", "Ivete Sangalo")
puts cancion.titulo
puts cancion.artista

# CON accesores

class Cancion
  def initialize(titulo, artista)
    @titulo = titulo
    @artista = artista
  end

  # accesor de lectura
  attr_reader :titulo, :artista

  # accesor de escritura
  # attr_writer :titulo

  # accesor de escritura y lectura
  # attr_accessor :titulo
end

cancion = Cancion.new("Brazil", "Ivete Sangalo")
puts cancion.titulo
puts cancion.artista