Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Anexo 1 Breve descripción de UML 245 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Anexo 1: Breve Descripción de UML Índice Visión general de UML 247 Elementos 248 Elementos estructurales 248 Elementos de comportamiento 251 Elementos de agrupación 252 Elementos de anotación 252 Relaciones 253 Diagramas 255 Diagrama de casos de uso 258 Diagrama de clases 267 Diagrama de objetos 275 Diagrama de secuencias 276 Diagrama de colaboración 278 Diagrama de estados 280 Diagrama de actividades 286 Diagrama de componentes 290 Diagrama de despliegue 292 Paquetes 294 246 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Visión general de UML UML es una gramática para expresar diseños de software orientado a objetos. Sus siglas significan, en español, Lenguaje Unificado de Modelado. No es la única notación que existe, pero es el estándar actual del llamado Object Management Group (OMG). Por tanto, conviene saber cómo expresarse en este lenguaje, advirtiendo que los lenguajes son dinámicos y que, a veces, no se utilizan de la misma forma por diferentes autores. Nosotros aprovecharemos UML para profundizar en los conceptos del software orientado a objetos. UML se expresa a través de elementos de construcción, de relaciones y de diagramas que contienen elementos y relaciones. Conocer esta estructura general ayuda a la comprensión del lenguaje en su conjunto y facilita prescindir de los detalles, hasta que no sean necesarios. 247 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Elementos Hay cuatro tipos de elementos en UML Elementos estructurales. Elementos de comportamiento. Elementos de agrupación. Elementos de anotación. Elementos estructurales Los elementos estructurales son la parte estática de los modelos de UML. Representan cosas que son conceptuales o materiales. Hay siete tipos de elementos estructurales: clases, interfaces, colaboraciones, casos de uso, clases activas, componentes y nodos. Clases: una clase es una descripción de un conjunto de objetos que comparten los mismos atributos, operaciones, relaciones y semántica. Gráficamente una clase se representa como un rectángulo, dividido en tres zonas que contienen el nombre, los atributos y las operaciones. Nombre Clase -atributos +operaciones() Interfaces: una interfaz es una colección de operaciones que especifican un servicio de una clase o componente, mostrando el comportamiento visible externamente de ese elemento. Una interfaz contiene sólo las especificaciones de las operaciones, es decir su signatura, pero no la implementación. Gráficamente las interfaces se representan con una figura en forma de piruleta, o como una clase con la etiqueta<<interface>>. «interface» NombreInterfaz NombreInterfaz 248 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Colaboración: una colaboración define una interacción y es una sociedad de roles y otros elementos que colaboran para proporcionar un comportamiento cooperativo mayor que la suma de los comportamientos de sus elementos. Por lo tanto, las colaboraciones tienen tanto dimensión estructural como de comportamiento. Una clase dada puede participar en varias colaboraciones. Estas colaboraciones representan, pues, la implementación de patrones que forman un sistema. Gráficamente una colaboración se representa como una elipse de borde discontinuo. Nombre colaboración Caso de uso: un caso de uso es una descripción de un conjunto de secuencias de acciones que un sistema ejecuta y que produce un resultado observable de interés particular. Un caso de uso se utiliza para estructurar los aspectos de comportamiento en un modelo. Un caso de uso es realizado por una colaboración. Gráficamente un caso de uso se representa como una elipse. Nombre Caso de uso Clase activa: una clase activa es una clase cuyos objetos tienen uno o más procesos o hilos de ejecución y, por lo tanto, pueden dar origen a actividades de control. Los objetos de una clase activa representan elementos cuyo comportamiento es concurrente con otros elementos. Gráficamente una clase activa se representa como una clase pero con líneas más gruesas. Nombre clase - atributos +operaciones 249 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Componente: un componente es una parte física y reemplazable de un sistema. En un sistema se pueden encontrar diferentes tipos de componentes de despliegue, tales como componentes COM+ o JavaBeans, así como componentes que sean artefactos del proceso de desarrollo, tales como archivos de código fuente. Un componente representa típicamente el empaquetamiento físico de diferentes elementos lógicos, como clases, interfaces y colaboraciones. Gráficamente un componente se representa como un rectángulo con dos pestañas. componente Nodo: un nodo es un elemento físico que existe en tiempo de ejecución y representa un recurso computacional, que por lo general dispone de algo de memoria y, con frecuencia, capacidad de procesamiento. Un conjunto de componentes puede residir en un nodo y también migrar de un nodo a otro. Gráficamente un nodo se representa como un cubo. Nodo 250 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Elementos de comportamiento Los elementos de comportamiento son las partes dinámicas de los modelos. Representan comportamiento en el tiempo y en el espacio. Hay dos tipos de elementos de comportamiento: interacciones y máquinas de estados. Interacciones: una interacción es un comportamiento que comprende un conjunto de mensajes intercambiados entre un conjunto de objetos, dentro de un contexto particular para alcanzar un propósito específico. El comportamiento de una sociedad de objetos o una operación individual puede especificarse mediante una interacción. Una interacción involucra otros elementos, incluyendo mensajes, secuencias de acción (el comportamiento invocado por un mensaje) y enlaces (conexiones entre objetos). Gráficamente, un mensaje se muestra como una línea dirigida etiquetada con el nombre de su operación. operación() Máquinas de estados: una máquina de estados especifica las secuencias de estados por las que pasa un objeto o una interacción durante su vida en respuesta a eventos. El comportamiento de una clase individual o una colaboración de clases puede especificarse con una máquina de estados. Una máquina de estados involucra otros elementos, incluyendo estados, transiciones (el flujo de un estado a otro), eventos (que disparan una transición) y actividades (la respuesta a una transición). Gráficamente un estado se representa como un rectángulo de esquinas redondeadas, incluyendo su nombre y sus subestados si los tiene. estado 251 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Elementos de agrupación Los elementos de agrupación son las partes organizativas de los modelos de UML, es decir, las cajas en las que puede descomponerse un modelo. Sólo hay un elemento de agrupación: el paquete. Paquetes: un paquete es un mecanismo de propósito general para organizar los elementos en grupos. Los paquetes son puramente conceptuales, sólo existen en tiempo de desarrollo. Un paquete puede contener elementos estructurales, elementos de comportamiento e incluso otros paquetes. Gráficamente un paquete se representa como una carpeta. Paquete Elementos de anotación Los elementos de anotación son la parte explicativa de los modelos de UML. Son comentarios que se pueden aplicar para describir, clarificar y hacer observaciones sobre cualquier elemento de un modelo. El principal elemento de anotación es la nota. Notas: una nota es simplemente un símbolo para mostrar restricciones y comentarios junto a un elemento o una colección de elementos. Gráficamente una nota se representa como un rectángulo con la esquina doblada. Comentario 252 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Relaciones Hay cuatro tipos de relaciones en UML: dependencia, generalización, asociación y realización. Dependencia Una dependencia es una relación semántica entre dos elementos, en la cual un cambio a un elemento (el elemento independiente) puede afectar a la semántica del otro elemento (el elemento dependiente). Gráficamente, una dependencia se representa como una línea discontinua dirigida, que incluye a veces una etiqueta. Asociación Una asociación es una relación estructural que describe un conjunto de enlaces, los cuales son conexiones entre objetos. La agregación es un tipo especial de asociación, que representa una relación estructural entre un todo y sus partes. Gráficamente, una asociación se representa como una línea continua, posiblemente dirigida, que a veces incluye una etiqueta, y a menudo incluye otros adornos, como la multiplicidad y los nombres de rol. La agregación se representa mediante un rombo situado en la parte del todo. Asociaciones y agregaciones 253 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Generalización Una generalización es una relación de especialización /generalización en la cual los objetos del elemento especializado (el hijo) pueden sustituir a los objetos del elemento general (el padre). De esta forma, el hijo comparte la estructura y el comportamiento del padre. Gráficamente, una relación de generalización se representa como una línea continua con un triángulo apuntando al padre. Realización Una 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 línea discontinua con una punta de flecha vacía. 254 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Diagramas Un diagrama es la representación gráfica de un conjunto de elementos, en general visualizado como un grafo conexo de nodos (elementos) y arcos (relaciones). Los diagramas se dibujan para visualizar un sistema desde diferentes perspectivas, de forma que un diagrama es una proyección de un sistema. Para todos los sistemas, excepto los más triviales, un diagrama representa una vista resumida de los elementos que constituyen un sistema. En teoría, un diagrama puede contener cualquier combinación de elementos y relaciones. En la práctica, sin embargo, sólo surge un pequeño número de combinaciones, las cuales son consistentes con las vista más útiles que comprenden la arquitectura de un sistema con gran cantidad de software. Por esta razón, UML incluye nueve de estos diagramas: 1. Diagrama de casos de uso. 2. Diagrama de clases. 3. Diagrama de objetos. 4. Diagrama de secuencias. 5. Diagrama de colaboración. 6. Diagrama de estados. 7. Diagrama de actividades. 8. Diagrama de componentes. 9. Diagrama de despliegue. 255 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Mecanismos de extensibilidad UML proporciona un lenguaje estándar para escribir planos software, pero no es posible que un lenguaje cerrado sea siempre suficiente para expresar todos los matices posibles de todos los modelos en todos los dominios y en todos los momentos. Por esta razón, UML proporciona tres mecanismos para extender el lenguaje de manera controlada. Estos mecanismos permiten configurar y extender UML a las necesidades de un proyecto y adaptarse a nuevas tecnologías de software. Los mecanismos de extensión de UML son: Estereotipos. Valores etiquetados. Restricciones. Estereotipos Un estereotipo extiende el vocabulario de UML, permitiendo crear nuevos tipos de bloques de construcción que deriven de los existentes pero sean específicos a un problema. Por ejemplo, si se está trabajando en un lenguaje de programación como Java o C++, a menudo será necesario modelar las excepciones. En estos lenguajes, las excepciones son simplemente clases, aunque se tratan de formas muy especiales. Normalmente sólo se permitirá que sean lanzadas y capturadas, nada más. Para modelar las excepciones se puede crear un estereotipo de una clase como muestra la figura. «exception» Nombre excepción Estereotipos El nuevo estereotipo <<exception>> será tratado como un bloque básico de construcción. 256 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Valores etiquetados Un valor etiquetado extiende las propiedades de un bloque de construcción de UML, permitiendo añadir nueva información en la especificación de ese elemento. Por ejemplo, si se está trabajando en un producto que atraviesa muchas versiones a lo largo del tiempo, se querrá registrar la versión y el autor de ciertas abstracciones críticas. La versión y el autor no son conceptos primitivos de UML. Pueden ser añadidos a cualquier bloque de construcción introduciendo nuevos valores etiquetados en dicho bloque. Por ejemplo, la figura muestra la clase ColaEventos en la que se han introducido los valores etiquetados versión y autor. ColaEventos {versión = 3.2, autor = ABC} añadir( ) quitar( ) vaciar( ) Valores etiquetados Restricciones Una restricción extiende la semántica de un bloque de construcción de UML, permitiendo añadir nuevas reglas o modificar las existentes. Por ejemplo, podríamos restringir la clase ColaEventos para que todas las adiciones se hiciesen en orden, añadiendo una restricción que lo indique explícitamente como muestra la figura. ColaEventos {versión = 3.2, autor = ABC} añadir( ) quitar( ) vaciar( ) {ordenado} Restricciones 257 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Casos de Uso Los casos de uso son una técnica de modelización de requisitos funcionales que facilitan la comunicación entre los desarrolladores, los clientes y los usuarios finales del sistema. Su lenguaje sencillo es comprensible por todos los implicados en el proceso de desarrollo de un sistema software. Los casos de uso, en su conjunto, describen los distintos usos que se le quiere dar al sistema. Por ejemplo, extraer dinero, ingresar dinero y consultar saldo, en un cajero automático. Cada uno de ellos constituye un Caso de Uso. Diagrama de casos de uso El diagrama de casos de uso especifica el comportamiento global del sistema y su interacción con el entorno. Muestra los servicios o funciones del sistema y los roles de los elementos del entorno con los que interactúan. Por ejemplo, el rol de usuario de un sistema. A estos roles de los elementos del entorno se les denomina actores. Observe que se distinguen los roles, no los elementos en sí. Cada servicio que el sistema deba realizar se modela como un caso de uso y cada rol de los elementos del entorno del sistema se modela como un actor. Gráficamente un caso de uso se representa con una elipse y un actor se representa con un monigote, independientemente de su naturaleza. La figura muestra el diagrama de casos de uso del cajero automático, ya citado. 258 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Cajero Automático Extraer Dinero Ingresar Dinero Cliente Consultar Saldo En el diagrama de casos de uso, se delimitan las fronteras del sistema mediante una caja. Los elementos que queden fuera de la caja forman parte del entorno. Sus roles, es decir, los actores nunca son parte del sistema, aunque interactúen con él. Los actores y los casos de uso se relacionan mediante asociaciones. Una relación de asociación entre un actor y un caso de uso indica que existe comunicación entre ellos y que pueden intercambiar información en ambos sentidos. Es posible que el número de casos de uso que necesitemos para modelar un sistema sea demasiado grande para mostrarse en un único diagrama sin perder visibilidad y comprensibilidad. En ese caso, el diagrama se puede organizar agrupando los casos de uso en paquetes. Actores Los actores, como se mencionó, representan los distintos roles que los elementos del entorno desempeñan respecto al sistema. Un actor representa a todos los elementos que desempeñan el mismo rol. En el ejemplo del cajero automático, el actor Cliente representa a todos los clientes del banco que pueden utilizar el cajero. 259 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Un mismo elemento puede desempeñar varios roles distintos, es decir, un elemento puede actuar como distintos actores en función del uso del sistema en cada momento. Es importante observar que los caso de uso están asociados con los actores, y no con los elementos concretos. Supongamos por ejemplo, que los empleados del banco pueden utilizar el sistema software del cajero para consultar su estado y realizar estadísticas sobre su uso. Tendríamos entonces un nuevo actor del sistema, Empleado, relacionado con dos nuevos casos de uso, Consultar Estado y Realizar Estadísticas. Si los empleados del banco son además clientes del banco, podrían también utilizar el cajero como el resto de los clientes, para sacar o ingresar dinero y consultar sus cuentas. Esto quiere decir que los empleados del banco actuarán unas veces como el actor Empleado y otras como el actor Cliente. Pero, no implica que el actor Empleado esté relacionado con los casos de uso Extraer Dinero, Ingresar Dinero y Consultar Saldo. Especificación de un caso de uso El comportamiento de un caso de uso se especifica describiendo la secuencia de acciones que el sistema debe llevar a cabo para proporcionar un servicio. Esta secuencia de acciones, habitualmente denominada flujo de eventos, debe escribirse de forma que sea lo suficientemente clara como para que alguien ajeno al sistema pueda entenderlo fácilmente. El estándar UML no se compromete con La especificación de un caso de uso. Los autores de UML solamente dan unas cuantas recomendaciones sobre el contenido de la especificación y la forma en qué debe escribirse. Para los autores de UML, la especificación de un caso de uso debería incluir al menos la siguiente información: Cómo y cuándo empieza y acaba el caso de uso. Cuándo el sistema interactúa con los actores y qué objetos intercambian. Flujo de eventos básico y flujos alternativos de comportamiento. 260 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Siguiendo estas recomendaciones proponemos la siguiente plantilla para escribir la especificación de un caso de uso. Esta plantilla además de las recomendaciones de UML incluye otras características recomendadas por A. Cockburn[], que consideramos muy útiles para la planificación y gestión del riesgo del proyecto. Nombre o título. Descripción: breve descripción textual del caso de uso. En esta descripción debería describirse cómo empieza el caso de uso y qué evento lo dispara. Actores: enumeración de los actores que participan en el caso de uso. Precondiciones: condiciones que debe tener el sistema antes de ejecutar el caso de uso. Poscondiciones: condiciones que debe tener el sistema después de ejecutar el caso de uso. Es recomendable incluir las condiciones en caso de éxito y en caso de fallo del caso de uso. Flujo de Eventos Principal: descripción de la interacción entre los actores y el sistema en condiciones normales, sin considerar ninguna excepción ni anomalía en la ejecución del caso de uso. Flujos de Eventos Alternativos: descripción de la interacción entre los actores y el sistema en condiciones excepcionales. Casos de Uso Relacionados. Requisitos No Funcionales Relacionados. Prioridad. Frecuencia. 261 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Riesgo asociado al caso de uso. El siguiente ejemplo muestra la especificación del caso de uso Extraer Dinero. Nombre o título: Extraer Dinero. Descripción: El cliente solicita al cajero la cantidad que quiere retirar. El cajero comprueba si el cliente dispone de esa cantidad en su cuenta y si es así se la entrega. Antes de realizar la operación el cliente debe ser validado. Para ello, el cliente introduce en el cajero su tarjeta y su número de PIN. El cliente tiene tres intentos para introducir el PIN correcto. Actores: Cliente. Precondiciones: Ninguna Postcondiciones: En caso de éxito: el cliente obtiene la cantidad de dinero que ha solicitado, la operación queda registrada y su saldo actualizado. En caso de fallo: Si el cliente introduce un número de PIN erróneo tres veces, su tarjeta queda invalidada. Si el cliente cancela la operación no hay ninguna postcondición. Flujo de Eventos Principal: 1. El cliente introduce la tarjeta en el cajero. 2. El cajero solicita el número de PIN. 3. El cliente introduce el número de PIN. 4. El cajero comprueba el número de PIN 262 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML 5. Si el PIN es correcto, el cajero solicita la cantidad a retirar. 6. El cliente introduce la cantidad a retirar. 7. El cajero comprueba si el cliente dispone de esa cantidad en su cuenta y si hay suficiente dinero en el cajero. 8. Si el cliente dispone de esa cantidad y el cajero tiene suficiente dinero, el cajero actualiza la cuenta del cliente, registra la operación, le entrega la tarjeta y el dinero al cliente y acaba el caso de uso. Flujos de Eventos Alternativos: 3.a. El cliente puede cancelar la operación. El cajero le devuelve la tarjeta y el caso de uso acaba 5.a. Si el PIN introducido no es correcto y el cliente aún no ha consumido los tres intentos se vuelve al paso 2. 5.b. Si el PIN introducido no es correcto y el cliente ya ha consumido los tres intentos, el cajero invalida la tarjeta y el caso de uso acaba. 6.a. El cliente puede cancelar la operación. El cajero le devuelve la tarjeta y el caso de uso acaba. 8.a Si el cliente no tiene esa cantidad disponible en su cuenta o el cajero no tiene suficiente dinero, se informa al cliente y se vuelve al paso 5. Casos de Uso Relacionados. Requisitos No Funcionales Relacionados. Prioridad: Alta. Frecuencia: Alta. Riesgo asociado al caso de uso: Medio. 263 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Relaciones entre casos de uso Los casos de uso pueden organizarse mediante las relaciones de uso (o inclusión), extensión y generalización entre ellos. Uso Esta relación significa que un caso de uso, llamado base, incorpora explícitamente el comportamiento de otro caso de uso. El caso de uso incorporado nunca se encuentra aislado. Es instanciado sólo como parte de algún caso de uso base que lo utiliza. La relación de uso se representa como una dependencia estereotipada con la etiqueta <<usa>>. La relación de uso se utiliza para delegar un comportamiento, común a varios casos de uso (los casos de uso base), a un sólo caso de uso. En el ejemplo del cajero automático todos los casos de uso tienen un comportamiento común: el cliente debe validarse antes de retirar dinero, ingresar dinero o consultar el saldo de su cuenta. En lugar de incluir este comportamiento en cada caso de uso, como hicimos cuando escribíamos la especificación de Extraer Dinero, podemos agruparlo en un nuevo caso de uso Validar Cliente. Los casos de uso Extraer Dinero, Ingresar Dinero y Consultar Dinero utilizarán el caso de uso Validar Cliente. La figura? muestra el diagrama de casos de uso del cajero empleando las relaciones de uso. Cajero Automático Extraer Dinero «uses» «uses» Ingresar Dinero «uses» Cliente Consultar Saldo 264 Validar Usuario Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML La relación de uso debe indicarse explícitamente en el flujo de eventos de la especificación del caso base. Por ejemplo, el flujo de eventos principal de la especificación del caso de uso Extraer Dinero debería escribirse de esta forma: Flujo de Eventos Principal: 1. Usa Validar Cliente. 2. El cajero solicita la cantidad a retirar. 3. El cliente introduce la cantidad a retirar. 4. El cajero comprueba si el cliente dispone de esa cantidad en su cuenta y si hay suficiente dinero en el cajero. 5. Si el cliente dispone de esa cantidad y el cajero tiene suficiente dinero, el cajero actualiza la cuenta del cliente, registra la operación y le entrega el dinero al cliente. Extensión La relación de extensión se utiliza para modelar la parte de un caso de uso que puede considerarse como un comportamiento opcional. De esta forma se separa el comportamiento opcional del obligatorio. Esta relación se representa como una dependencia estereotipada como <<extiende>>. «extends» Caso Base Extensión Los puntos de extensión pueden indicarse en el diagrama con una etiqueta en la relación de extensión, indicando en el flujo de eventos del caso base la localización del punto de extensión. Generalización La relación de generalización entre casos de uso es como la generalización entre clases. Significa que el caso de uso hijo hereda el comportamiento y el significado del caso de 265 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML uso padre. El hijo puede añadir o redefinir el comportamiento del padre y puede ser colocado en cualquier lugar donde aparezca el padre. Supongamos que el cajero automático pudiese validar al cliente de dos formas distintas: comprobando el PIN de la tarjeta o examinando la retina. El caso de uso padre Validar Usuario podría tener dos casos de uso hijos especializados Comprobar PIN y Examinar Retina. La relación de generalización se representa igual que la generalización entre clases, con una línea continua con la punta de flecha vacía. Caso General Caso Específico Relaciones entre actores Los actores sólo pueden tener entre ellos relaciones de generalización. Se pueden definir categorías generales de actores y especializarlos mediante relaciones de especialización. La relación de generalización entre actores se representa igual que la generalización entre clases y entre casos de uso, con una línea continua con la punta de flecha vacía. Actor General Actor Específico 266 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Diagrama de clases Un diagrama de clases muestra las clases que componen el sistema y las relaciones que existen entre ellos. Este diagrama se utiliza para modelar la vista de diseño estructural de un sistema. Los diagramas de clases además, pueden contener paquetes. Clases Una clase es la definición de un conjunto de objetos que comparten los mismos atributos, operaciones, relaciones y semántica. Las clases se representan gráficamente con una caja dividida en tres zonas: en la zona superior se escribe el nombre de la clase, en la zona central los atributos y en la inferior las operaciones. En algunas ocasiones, para simplificar el diagrama, las clases se representan con una caja que contiene sólo el nombre. Nombre Clase Nombre Clase -atributos +operaciones() Para especificar que una clase es abstracta, es decir que contiene al menos una operación abstracta, se escribe el nombre de la clase en cursiva. El número de instancias que pueden crearse de una clase es su multiplicidad. Generalmente la multiplicidad de una clase es ilimitada, en un sistema suele haber muchas instancias u objetos de una clase ejecutándose. Sin embargo, a veces es necesario restringir a un número determinado el número de instancias de una clase. En estos casos, la multiplicidad se escribe en la esquina superior derecha de la clase. UML permite especificar dos características importantes de los elementos (atributos y operaciones) de una clase: la visibilidad y el alcance. 267 Curso de OO dirigido por la introducción de ambigüedad - Anexo 1: Breve descripción de UML Visibilidad: los elementos de una clase pueden ser públicos, protegidos o privados. Los elementos públicos son visibles para los objetos de todas las clases del sistema. Un elemento público va precedido del signo +. Los elementos protegidos sólo son visibles dentro de la clase y de las clases hijas. Un elemento protegido va precedido del signo #. Los elementos privados solamente son visibles dentro de la clase. Un elemento privado va precedido del signo -. - Alcance: se pueden especificar dos niveles de alcance: Instancia: cada instancia de la clase tiene su propio valor del elemento. Clase: sólo hay un valor del elemento para todas las instancias de la clase. (El alcance de clase es equivalente al uso de “static” en C++ y Java). Para indicar que un elemento tiene alcance de clase se subraya. Atributos La sintaxis de un atributo en UML es: [visibilidad] nombre [multiplicidad] [:tipo] [= valor inicial] [{propiedades}] La visibilidad, como se explicó anteriormente, indica si el atributo es público, protegido o privado. La multiplicidad de un atributo es el número de instancias del atributo que se pueden crear. Se especifica mediante una expresión encerrada entre corchetes. Por ejemplo: impresora [1..5]: Impresora indica que pueden existir de 1 a 5 instancias del atributo impresora. La multiplicidad suele utilizarse para especificar vectores de atributos. 268 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Las propiedades predefinidas para los atributos son: changeable: no hay restricciones para cambiar el valor del atributo. addOnly: esta propiedad sólo se aplica a los atributos de multiplicidad mayor que uno. Indica que, un valor asignado no se puede borrar ni modificar, sólo se permite añadir nuevos valores al atributo. frozen: no se puede modificar el valor del atributo. Operaciones La sintaxis de una operación en UML es: [visibilidad] nombre [(lista de parámetros)] [:tipo de retorno] [{propiedades}] La visibilidad indica si la operación es pública, protegida o privada. Para especificar que una operación es abstracta se escribe el nombre en cursiva. Una operación abstracta no tiene implementación, sólo tiene cabecera. La implementación la proporcionan las clases hijas redefiniendo la operación. La sintaxis de un parámetro es: [dirección] nombre [:tipo] [= valor por omisión] La dirección de un parámetro puede tomar tres valores: in: parámetro de entrada. out: parámetro de salida. in/out: parámetro de entrada y salida. Las propiedades predefinidas para una operación son: leaf: la operación no puede ser redefinida en las clases hijas. 269 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML isQuery: la ejecución de la operación no modifica el estado del sistema. sequential: la semántica y la integridad del objeto no se pueden garantizar en presencia de múltiples flujos de control. Los objetos invocadores de la operación deben coordinarse para que en el objeto sólo haya un único flujo al mismo tiempo. guarded: la operación tiene guardas. La semántica e integridad del objeto se garantizan en presencia de múltiples flujos de control, tratando secuencialmente todas las llamadas a las operaciones con guardas del objeto. concurrent: la semántica y la integridad del objeto se garantizan en presencia de múltiples flujos tratando la operación como atómica. Las propiedades sequential, guarded y concurrent sólo se emplean cuando existe concurrencia, en presencia de objetos activos, procesos o hilos. Relaciones Una clase puede tener una relación consigo misma, indicando que los objetos de esa clase están conectados entre sí. Las relaciones se dibujan con una línea, empleando un tipo distinto de línea para cada tipo de relación o un símbolo específico. Dependencia Cuando objetos de una clase utilizan objetos de otra clase existe una relación de dependencia entre sus clases respectivas. Esta relación se representa en el diagrama de clases con una flecha discontinua en el sentido del elemento que se usa. Las clases, cuyos objetos usan los de otra clase, dependen de la especificación de la clase usada. Si cambia la especificación, habrá que hacer cambios en las clases que la usan. 270 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Las dependencias generalmente se utilizan para indicar que una clase utiliza a otra como argumento en alguna operación o sus objetos utilizan alguna de las operaciones de la otra clase. LectorTarjeta Tarjeta Se puede poner nombre a las dependencias para mejorar la comprensión del diagrama, pero generalmente no es necesario. Asociación Una asociación es una relación estructural. Esta relación expresa que se puede navegar desde los objetos de una clase hasta los objetos de la otra clase. La asociación se representa con una línea continua. Cliente Persona Las asociaciones se suelen emplear para indicar que una clase contiene un atributo de la otra clase. En UML se puede especificar el nombre de una asociación, el rol de cada clase y su multiplicidad o cardinalidad. Clave Usuario Una asociación es, en principio, bidireccional. Cuando se quiere limitar la navegación en un sólo sentido se dibuja una flecha que indique explícitamente el sentido permitido. Por ejemplo, en la figura los objetos de la clase Clave pueden acceder a los de la clase Usuario, pero no al revés. Una asociación entre dos clases es una relación entre iguales, conceptualmente ninguna de las clases tiene más importancia que otra. Sin embargo, a 271 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML veces conviene destacar que una de las clases es un “todo” del que la otra clase forma “parte”. A esta relación “todo/partes” se le llama agregación simple. Gráficamente se representa con un rombo vacío en el extremo de la clase “todo”. Biblioteca Libro La agregación simple sólo es una relación conceptual, no tiene implicaciones en el comportamiento de las clases. Existe otro tipo de agregación, la composición o agregación compuesta. La composición es también una relación “todo/partes”, pero con fuertes implicaciones de comportamiento. La composición liga la existencia de las partes al todo: si el todo desaparece también desaparecen sus partes. Gráficamente se representa con un rombo relleno en el extremo de la clase “todo”. Libro Estado Libro Generalización La generalización o herencia expresa una relación entre una clase genérica y una o varias clases específicas. A la clase genérica se le llama clase madre y a las clases específicas hijas. La generalización indica que las hijas heredan los atributos, operaciones y relaciones de la clase madre (sólo se heredarán los elementos que sean públicos o protegidos). Las hijas pueden redefinir los elementos que heredan del padre y añadir sus propios atributos, operaciones y relaciones. Gráficamente, la generalización se representa con una línea continua acabada en una punta de flecha vacía. 272 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Figura #color +dibujar() +borrar() Triangulo Rectángulo Circulo -punto1 -punto2 +dibujar() -punto1 -punto2 -punto3 +dibujar() -centro -radio +dibujar() UML permite especificar herencias múltiples, es decir que una clase herede el comportamiento de varias clases madre. Pero, hay que tener cuidado con el uso de la herencia múltiple. Afortunadamente no todos los lenguajes permiten su implementación. Interfaces y realizaciones A las clases abstractas puras, es decir, a las clases que no contienen ninguna implementación, se les llama interfaces. En UML una interfaz es una colección de operaciones que sirven para especificar los servicios de una clase o un componente. Una interfaz sólo contiene las cabeceras de las operaciones, no su implementación. (Una interfaz de UML se corresponde con una clase virtual pura de C++ y con una “interface” de Java). Gráficamente una interfaz se puede representar de forma expandida como una clase estereotipada con la etiqueta <<interface>> o, en su forma abreviada, con una figura en forma de piruleta. «interface» NombreInterfaz NombreInterfaz 273 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML En los diagramas de clases se suele utilizar la forma expandida para representar las interfaces. La forma abreviada generalmente se usa en los diagramas de componentes. Hay dos relaciones que pueden existir entre una clase y una interfaz: la dependencia y la realización. La dependencia entre una clase y una interfaz tiene el mismo significado y representación que entre dos clases, indica que la clase usa la interfaz. Para que una interfaz se pueda usar hace falta que otra clase implemente las operaciones que la interfaz especifica. A esta relación entre la interfaz y la clase que la implementa se le llama realización. La realización indica que la clase implementa todas las operaciones de la interfaz. Gráficamente la realización se representa como una generalización con la línea discontinua. Objetivo -id -posicionActual +establecerPosición() +establecerVelocidad() +posiciónEsperada() «interface» Observador +actualizar() RastreadorDeObjetivo +actualizar() 274 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Diagrama de objetos Un diagrama de objetos muestra un conjunto de objetos y sus relaciones en un instante de tiempo determinado. Puede verse como una fotografía del sistema que muestra el estado de los objetos en ese instante. La representación gráfica de un objeto en UML es igual que la de una clase pero con el nombre subrayado. Para mostrar el estado de un objeto, se indica el valor de sus atributos y sus objetos agregados. La única relación entre objetos que se puede representar en UML es el enlace. Un enlace indica una conexión entre dos objetos. Dos objetos pueden estar conectados si existe una asociación o una dependencia entre las clases que instancian. c : Compañía d1 : Departamento d2 : Departamento nombre : String = "Ventas" nombre : String = "I+D" p : Persona nombre : String = "Francisco" ID_Empleado : unsigned long(idl) = 3421 cargo : String = "Director de Ventas" Los diagramas de objetos pueden contener paquetes y, cuando se quiere mostrar la clase que hay detrás de cada instancia, también pueden contener clases. 275 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Diagramas de interacción Los diagramas de interacción muestran comportamientos parciales del sistema, describiendo la secuencia de mensajes que intercambian los objetos para llevar a cabo una tarea. Algunos autores llaman a este tipo de diagramas escenarios, quizás porque representan escenas del comportamiento del software. Cada diagrama sólo refleja un aspecto concreto de un comportamiento particular del sistema y no el comportamiento global. Por tanto, los diagramas de interacción muestran una visión fragmentada de la dinámica del sistema. En UML existen dos tipos de diagramas de interacción: los diagramas de secuencia y los diagramas de colaboración. Ambos son equivalentes, la diferencia entre ellos está en los aspectos que resaltan. Los diagramas de secuencia destacan el orden temporal de los mensajes, mientras que los diagramas de colaboración destacan la organización estructural de los objetos. Diagrama de secuencias Los diagramas de secuencias se han convertido en una de las representaciones más populares de UML debido a su simplicidad y capacidad de expresión. Su éxito radica en que es muy sencillo dibujarlos y, aún más importante, es muy fácil interpretarlos correctamente. 276 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML c:Cliente p:ProxyODBC <<create>>() :Transaccion establecerAcciones(a, d, o) estableceValores(d, 3.4) estableceValores(a, "CO") éxito() destroy() Los objetos que participan en la interacción se dibujan en la parte superior del diagrama horizontalmente. Los objetos se representan igual que las clases pero con el nombre subrayado. Debajo de cada objeto se dibuja una línea vertical discontinua llamada línea de vida. Esta línea indica el tiempo de existencia del objeto. Los mensajes se representan con una flecha desde la línea de vida del objeto que envía el mensaje hacía la línea de vida del objeto que lo recibe. La etiqueta de la flecha indica la operación del objeto receptor que se invoca, incluyendo los parámetros. Si la operación devuelve algún valor se dibuja una flecha discontinua apuntando hacia el objeto emisor, etiquetada con el nombre del valor de retorno. Generalmente, los objetos que participan en una interacción existen durante todo el tiempo que dura dicha interacción. Siendo así, los objetos se sitúan en la parte superior y sus líneas de vida se prolongan a lo largo de todo del diagrama. Sin embargo, también pueden crearse y destruirse objetos durante la interacción. La creación y la destrucción 277 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML de un objeto se indican mediante mensajes estereotipados con <<create>> y <<destroy>> respectivamente. Cuando un objeto es creado durante la interacción, se sitúa en el diagrama alineado con el mensaje de creación y no en la parte superior. La destrucción de un objeto se muestra dibujando una x grande al final de su línea vida. Los rectángulos que aparecen sobre las líneas de vida de los objetos se llaman focos de control. El foco de control representa el período de tiempo durante el cual el objeto está ejecutando una acción y tiene el control del sistema. En los diagramas de secuencias, los caminos alternativos de una bifurcación se pueden representar con mensajes separados que parten del mismo punto. Pero, esta forma de representar las bifurcaciones hace menos comprensibles los diagramas. En general, los diagramas de secuencia no reflejan alternativas o bifurcaciones. Si existe un camino alternativo se representa en otro diagrama de secuencia. El inconveniente de esta decisión es que requiere un número mayor de diagramas, pero resultan más comprensibles. Además, tiene la virtud de independizar un camino de otro. Así se puede diseñar un camino y después el otro, sin modificar lo que ya está hecho. Para el software evolutivo, es una cualidad importante. Los diagramas de secuencias se utilizan principalmente para modelar la vista de diseño dinámica, o de comportamiento, del sistema. Aunque, debido a su éxito, también es frecuente utilizarlos para describir los flujos de eventos de los casos de uso. Diagrama de colaboración Un diagrama de colaboración es un diagrama de interacción que resalta la organización estructural de los objetos que envían y reciben los mensajes. Este tipo de diagrama muestra un conjunto de objetos, enlaces entre ellos y los mensajes que intercambian. Un diagrama de colaboración es un grafo, donde los nodos del grafo son los objetos y los arcos son los enlaces. Un enlace es una instancia de una asociación o una dependencia entre clases. Se representa con una línea continua que une los dos objetos. 278 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML c:Cliente 1: <<create>> 2: establecerAcciones(a,d,o) 3: <<destroy>> p:ProxyODBC :Transaccion 2.1: establecerValores(d,3.4) 2.2: establecerValores(a,"CO") Los mensajes se escriben junto a los enlaces, indicando el sentido con una flecha que apunta hacia al objeto receptor y numerándolos para expresar el orden temporal. Se pueden representar mensajes anidados utilizando la numeración decimal de Dewey (1 es el primer mensaje, 1.1 es el primer mensaje dentro del mensaje 1, 1.2 es el segundo mensaje dentro del mensaje 1,...) Las iteraciones se representan anteponiendo al número del mensaje el símbolo *. Opcionalmente, se puede añadir una expresión que indique hasta cuando se repite la iteración. Para modelar una bifurcación, el número de secuencia del mensaje se precede de una cláusula de condición. Los caminos alternativos de una bifurcación tendrán el mismo número de secuencia. Pero, cada camino debe ser distinguible de forma única por una condición que no se solape con las otras. 279 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Diagrama de estados En UML los diagramas de estados se utilizan para modelar el comportamiento de un objeto dirigido por eventos. Aunque también pueden utilizarse para mostrar el comportamiento del sistema global o de subsistemas. Un diagrama de estados modela la vida de un objeto mediante una máquina de estados. Cada estado representa una situación durante la cual el objeto satisface alguna condición, realiza alguna actividad o espera algún evento. Los estados se dibujan con una caja con las esquinas redondeadas. Se pueden definir dos estados especiales: Estado inicial: indica el punto de comienzo de la ejecución de la máquina de estados. Se representa con un círculo negro. Estado final: indica la terminación de la ejecución de la máquina de estados. Se representa con un círculo negro dentro de un círculo blanco. Las transiciones entre estados se dibujan con una flecha continua desde el estado origen al estado destino. En cada transición se puede especificar: Evento de disparo: es el evento cuya recepción por el objeto cuando se encuentra en el estado origen provoca la transición el estado destino. Por ejemplo, en la Figura 1, el evento rechazado dispara la transición del estado Confirmar crédito a Cancelar Pedido. Condición de guarda: es una expresión booleana que se evalúa cuando se recibe el evento disparador. La transición solamente se dispara si la expresión toma el valor verdadero. Las condiciones de guarda se escriben entre corchetes a continuación del evento de disparo. Por ejemplo: en la transición “pedido recibido [precio>límite]”, de la Figura 1, pedido recibido indica el evento de disparo y [precio>límite ] la condición de guarda. 280 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Acción: es una computación atómica que se ejecuta cuando se dispara la transición. Las acciones son atómicas, es decir, no pueden ser interrumpidas por ningún evento y, por lo tanto se ejecutan hasta su terminación. Una acción puede ser una llamada a una operación, el envío de una señal, la creación de un objeto,... Las acciones se escriben, precedidas del símbolo “/”, a continuación del evento de disparo y de la guarda. Por ejemplo: en la transición aprobado/cargarCuenta( ) de la figura, aprobado indica el evento de disparo y cargarCuenta() la acción que se ejecuta cuando se realiza la transición. A las transiciones en las cuales el estado origen y el destino son el mismo se les llama autotransiciones. estado inicial evento agotado(producto)/renovarStock(producto) autotransición pedido recibido [precio<límite] Procesar Pedido estado final guarda Esperando acción **Fig pedido recibido [precio>límite] aprobado/cargarCuenta() estado transición Confirmar Crédito rechazado 281 Cancelar Pedido Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Características Avanzadas Utilizando solamente las características básicas de los estados y las transiciones se puede modelar la mayoría de los comportamientos de los objetos. Sin embargo, las máquinas de estados de UML tienen varias características avanzadas que pueden ayudar a modelar comportamientos complejos. En UML los estados pueden incluir: Acciones de entrada y salida: acciones atómicas que se ejecutan siempre que se entra o se sale del estado. Las acciones de entrada se etiquetan con el evento especial entry y las de salida con exit. Transiciones internas: transiciones que se manejan sin cambiar de estado. Las transiciones internas son ligeramente diferentes de las autotransiciones. Una autotransición implica salir del estado y volver a entrar en él. Por lo tanto, primero se ejecuta la acción de salida del estado, después la acción de la transición y por último la acción de entrada al estado. En cambio, en una transición interna no se abandona el estado y sólo se ejecuta la acción asociada a la transición. Actividades: conjunto de acciones que realiza el objeto mientras se encuentra en ese estado. Una acción no puede ser interrumpida por un evento, pero una actividad sí. A diferencia de las transiciones internas, las actividades no son disparadas por ningún evento externo. Se etiquetan con el evento especial do. Eventos diferidos: lista de eventos que no se manejan en este estado, sino que se posponen y se añaden a una cola para ser manejados por el objeto en otro estado. Los eventos diferidos se etiquetan con la acción especial defer. 282 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Rastreando acción de entrada acción de salida transición interna actividad evento diferido entry/activarModo(enRastreo) exit/activarModo(noRastreo) nuevoObjetivo/rastreador.Adquirir( ) do/seguirObjetivo autoTest/defer Además, en UML los estados de una máquina pueden contener subestados o estados anidados. A un estado que contiene subestados se le llama estado compuesto. Los estados compuestos se representan igual que los simples, pero contienen en su interior una máquina de estados que describe el flujo de control entre los subestados. Las transiciones de entrada a un estado compuesto pueden activar el propio estado compuesto o uno de sus subestados. Para activar el estado compuesto es necesario que la máquina de subestados tenga definido un estado inicial. En tal caso, cuando se dispara una transición de entrada al estado compuesto, se ejecuta la acción de entrada y el flujo de control pasa al subestado inicial. Si no se define un subestado inicial, las transiciones de entrada deben dirigirse a los subestados y no al estado compuesto. Cuando se dispara una transición de entrada a un subestado, primero se ejecuta la acción de entrada del estado compuesto, a continuación el flujo de control pasa al subestado y se ejecuta su acción de entrada. Las transiciones de salida pueden tener como origen el estado compuesto o un subestado. Si el origen es un subestado, cuando se dispara la transición se ejecuta primero la acción de salida del subestado, a continuación la acción del estado compuesto y por último la acción asociada a la transición. Si el origen de la transición de salida es el estado compuesto, cuando se dispara la transición se interrumpe la ejecución de la máquina anidada; ejecutándose primero la acción de salida del subestado que tuviese el control en ese momento, después la del estado compuesto y por último la acción asociada a la transición. 283 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML estado compuesto Inactivo llamada Recibiendo colgar cabeceraOK enviar Procesando Conectado verificaciónOK Transmisión Limpiando subestado entry/ descolgar exit/ desconectar Cada vez que se dispara una transición de entrada a un estado compuesto, la máquina de estados anidada comienza de nuevo su ejecución en el estado inicial. Sin embargo, en algunas ocasiones puede resultar útil que la máquina recuerde el último estado en el que se encontraba y comience su ejecución desde ese estado. Para modelar este tipo de comportamiento UML introduce los estados de historia. Un estado de historia se representa con un círculo con el símbolo H. estado de historia CopiaDeSeguridad H Orden Recoger consulta Copiar transición inicial Limpiar El estado de historia debe tener una única transición de salida hacia otro subestado. La primera vez que se activa el estado compuesto, aún no hay historia, y se ejecuta esta transición. Si se dispara una transición de salida, el estado de historia recordará el último estado que estaba ejecutándose en la máquina antes de salir del estado 284 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML compuesto. A partir de ese momento ya hay historia. Cuando se produzca una nueva transición de entrada el control pasará al último estado activo. Los estados compuestos pueden contener subestados concurrentes. Si todos los subestados son secuenciales, el estado compuesto contendrá sólo una máquina anidada. Si existen subestados concurrentes, el estado compuesto contendrá varias máquinas, una por cada tado concurrente. división Inactivo unión Subestados concurrentes mantener Mantenimiento Pruebas Probar periféricos ManejoOrdenes Autodiagnosis teclaPulsada Espera [no continuar] Orden [continuar] Cuando se activa un estado compuesto que contiene subestados concurrentes, el flujo de control se divide en tantos flujos como máquinas anidadas haya. Las máquinas se ejecutarán en paralelo mientras el estado compuesto esté activo. Si una de las máquinas llega a su estado final, espera en ese estado a que todas las demás acaben de ejecutarse. Cuando todas las máquinas han alcanzado su estado final, el control vuelve a unirse en un único flujo. Las máquinas de subestados concurrentes no pueden contener estados de historia. 285 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Diagrama de actividades Los diagramas de actividades de UML son similares a los diagramas de flujo tradicionales. Generalmente se utilizan para modelar flujos de trabajo o para describir detalladamente una operación. En UML los diagramas de actividades son un caso particular de los diagramas de estado que muestran un flujo de control. En estos diagramas los estados representan actividades o acciones. Una acción es una operación atómica indivisible que no puede ser interrumpida durante su ejecución. Una actividad es una operación no atómica que puede descomponerse en otras actividades o acciones y que puede ser interrumpida durante su ejecución. Gráficamente no hay ninguna diferencia entre un estado de actividad y un estado de acción, ambos se representan con una caja de bordes redondeados. Para indicar el estado inicial y final de la actividad global se utilizan los mismos símbolos que en los diagramas de estado: un círculo negro para el estado inicial y un círculo negro dentro de un círculo blanco para el estado final. Cuando se completa la actividad o la acción de un estado, el flujo de control pasa inmediatamente al estado siguiente. La transición de un estado a otro se indica con una flecha continua. Como en un cualquier diagrama de flujo se pueden especificar bifurcaciones dibujándolas con un rombo. Una bifurcación tiene una transición de entrada y dos o más transiciones de salida. En cada transición de salida se escribe una expresión entre corchetes, llamada guarda, que indica las condiciones bajo las que se sigue esa transición. Las guardas deben cubrir todas las condiciones posibles de salida para que el flujo de control no se interrumpa en ningún caso. Pero, para evitar ambigüedades en el flujo de control, las guardas no deben solaparse. 286 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Establecer pedido [pedido único] Cargar tarjeta de crédito [suscripción] Cargar a la cuenta En un diagrama de actividades, es posible especificar flujos de control concurrentes. La unión y la división de estos flujos se indican mediante barras de sincronización. Una barra de sincronización se representa con una línea continua ancha que une varios flujos concurrentes en uno sólo, o divide un único flujo en varios hilos concurrentes. 287 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Solicitar producto Procesar pedido Extraer artículos Enviar Pedido Recibir pedido Facturar al cliente Pagar factura Cerrar pedido Cuando se modelan flujos de trabajo de organizaciones, resulta muy útil dividir el diagrama de actividades en grupos que se correspondan con las distintas divisiones o unidades de la organización. Dentro de cada grupo se encontrarán las actividades de las que es responsable cada unidad. En UML, a estos grupos se les denomina calles porque el aspecto del diagrama recuerda a una pista de atletismo dividida en calles. Aunque no es muy frecuente, se pueden incluir en el diagrama los objetos implicados en el flujo de control. Los objetos se unen con una dependencia a la actividad que los crea, modifica o destruye. A este uso de los objetos y las relaciones de dependencia se le denomina flujo de objetos. Debajo del nombre del objeto, se puede mostrar el estado del objeto con un nombre entre corchetes y el valor de sus atributos en un compartimento. 288 Curso de OO dirigido por la introducción de ambigüedad Cliente Anexo 1: Breve descripción de UML Ventas Almacén Solicitar producto Procesar pedido Extraer artículos o:Pedido [en progreso] Enviar pedido o:Pedido [completado] RecibirPedido Pagar Factura b:Factura [pagada] Facturar al cliente b:Factura [impagada] Cerrar pedido 289 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Diagrama de componentes En UML los componentes representan elemento físicos del sistema, por ejemplo ejecutables, páginas HTML, librerías, tablas, ficheros, etc. Gráficamente, un componente se dibuja mediante una caja con pestañas. Componente Un diagrama de componentes muestra la organización y las dependencias entre un conjunto de componentes. Los diagramas de componentes pueden contener paquetes para organizar los elementos. Los componentes se comunican mediante interfaces. Es decir, un componente ofrece sus servicios a los demás exportando interfaces y los otros componentes acceden a sus servicios importando estas interfaces. La exportación de una interfaz se puede representar de dos formas. Si se utiliza la forma expandida de la interfaz para hacer explícitas sus operaciones, la exportación se representa como una relación de realización. Figura 1. Sin embargo, en los diagramas de componentes, lo más frecuente es utilizar la forma simplificada de la interfaz (la piruleta) y representar la exportación mediante una línea continua que une el componente a la interfaz.. Figura 2. La importación de una interfaz se representa mediante una relación de dependencia. «interface» ObservadorDeImagen +actualizarImagen() imagen.java componente.java Figura 1. 290 Curso de OO dirigido por la introducción de ambigüedad imagen.java Anexo 1: Breve descripción de UML Observador De Imagen componente.java Figura 2. UML define cinco estereotipos estándar aplicables a los componentes: executable: especifica un componente que se puede ejecutar en un nodo (archivos .EXE). library: especifica una librería de objetos estática o dinámica (DLL). table: especifica una tabla de una base de datos. file: especifica un fichero que puede contener código fuente o datos. document: especifica un documento. Muchas herramientas de modelado proporcionan iconos específicos para representar estos estereotipos. Estos iconos no forman parte del estándar UML como tal, pero su uso está tan extendido entre la comunidad de usuarios que pueden considerarse un estándar “de facto”. Además, las herramientas también suelen incluir estereotipos para modelar aplicaciones Web que aún no forman parte de UML, pero posiblemente estarán incorporados en próximas versiones. Generalmente, cuando se utilizan estos estereotipos, no se muestran las interfaces en el diagrama. En su lugar, se utiliza una notación simplificada, dibujando las dependencias directamente del componente que importa la interfaz hacia el componente que la exporta. find.html index.html find.exe 291 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Diagrama de despliegue Los diagramas de despliegue modelan la topología del hardware sobre el que se ejecuta el sistema software. Este tipo de diagramas suele utilizarse para modelar sistemas distribuidos o sistemas empotrados. En los sistemas monolíticos, generalmente, resultan innecesarios. Un diagrama de despliegue muestra la configuración de los nodos del sistema. En UML, un nodo es un elemento físico que existe en tiempo de ejecución y representa un recurso computacional que, generalmente, tiene alguna memoria y, a menudo, capacidad de procesamiento. Habitualmente los nodos representan procesadores y dispositivos hardware. Gráficamente, un nodo se dibuja como un cubo. Las conexiones físicas entre los nodos se representan mediante relaciones de asociación. terminal servidor unidad RAID consola Figura 1 Los diagramas de despliegue pueden contener paquetes para organizar los nodos. Cuando se modela la topología de los sistemas distribuidos y empotrados, es importante especificar la distribución física de los componentes software sobre los nodos. A 292 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML menudo, resulta útil visualizar esta distribución en el diagrama de despliegue. Para ello, UML proporciona dos alternativas: añadir a cada nodo un compartimento adicional con la lista de los componentes que se ejecutan sobre él. Figura 2. incluir en el diagrama de despliegue los componentes y conectar, cada nodo con los componentes que se ejecutan sobre él, mediante una relación de dependencia. Figura 3. terminal Despliega user.exe servidor unidad RAID Despliega dbadmin.exe consola Despliega admin.exe config.exe Figura 2. user.exe terminal servidor admin.exe consola dbadmin.exe config.exe Figura 3. 293 unidad RAID Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Paquetes Un paquete es un mecanismo de propósito general para organizar elementos en grupos. Gráficamente se representa como una carpeta. <<Nombre >> Los paquetes se utilizan para organizar los elementos de los diagramas en grupos a los que se puede dar un nombre y manejar como un conjunto. Si estamos desarrollando una aplicación trivial, probablemente podremos representar todo el sistema en un diagrama que contenga unos cuantos elementos y resulte fácil de entender e interpretar. Pero, en un sistema complejo, el número de elementos y de relaciones necesarias para modelar el sistema completo puede exceder la capacidad humana de comprensión. Por esta razón se agrupan los elementos en paquetes y el contenido de cada paquete se muestra en un diagrama distinto. Los paquetes pueden tener relaciones de dependencia y generalización. La relación de dependencia indica que los elementos de un paquete utilizan o importan los elementos del paquete del que dependen. La generalización entre paquetes es similar a la generalización entre clases, los paquetes hijos heredan los elementos del paquete padre. La generalización entre paquetes suele utilizarse para especificar familias de paquetes. Existen dos estereotipos de la relación de dependencia entre paquetes, <<import>> y <<access>>. Ambos especifican que el paquete origen tiene acceso a los elementos del paquete destino. La diferencia es que <<import>> añade al espacio de nombres del origen el contenido del destino, evitando la calificación de nombres. 294 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML Aplicacion IGU IGU Windows IGU Mac Figura 1. Relaciones entre paquetes Los paquetes deben agrupar elementos cercanos semánticamente y que suelen cambiar juntos, tratando de minimizar las dependencias entre paquetes. De esta forma se facilita el mantenimiento y la evolución del sistema. Ante un cambio en el sistema, las modificaciones afectarán principalmente a los elementos de un paquete. Aunque habrá que revisar todos los paquetes que tengan alguna dependencia con el paquete que se ha modificado. UML permite mostrar explícitamente el contenido de un paquete. En este caso, el nombre del paquete se coloca en la pestaña de la carpeta. (En la práctica no suele mostrarse el contenido de los paquetes de esta forma, sino que se accede al contenido de cada paquete mediante herramientas software). Generalmente, los elementos de un paquete son públicos. Pero UML admite la posibilidad de controlar la visibilidad de los elementos de un paquete del mismo modo que se controla la visibilidad de los atributos y las operaciones dentro de una clase. Un elemento de un paquete puede ser: Público: visibles en cualquier paquete que importe el paquete que lo contiene. Protegido: sólo es visible dentro del paquete que lo contiene y de sus hijos. Privado: sólo es visible dentro del paquete que lo contiene. 295 Curso de OO dirigido por la introducción de ambigüedad Anexo 1: Breve descripción de UML La notación para especificar la visibilidad de los elementos de un paquete es la misma que se usa para las clases: un elemento público va precedido del símbolo +, un elemento va precedido del símbolo # y un elemento privado va precedido del símbolo - . Por defecto los elementos de un paquete se consideran públicos. 296