Beruflich Dokumente
Kultur Dokumente
PROFESOR:
IMPORTANTE:
Este documento es de uso exclusivo para alumnos de la asignatura de “Ingeniería del Software” de
las titulaciones I.T.I.G. e Ingeniería en Electrónica de la Universidad de Alcalá.
TEMARIO:
UML
Introducción.
Diagrama de Casos de uso.
Diagrama de Secuencia.
Diagrama de Colaboración.
Diagrama de Estados.
Diagrama de Actividades.
Diagrama de Clases.
Diagrama de Objetos.
Diagrama de Componentes.
Diagrama de Despliegue.
Proceso Unificado de Rational.
Generación de código.
BIBLIOGRAFÍA:
• Ayuda de Rational Rose. En especial, para la generación de código se puede consultar en Ayuda
Contenido Rose C++ las secciones Concepts y Reference Model-to-Code correspondences.
• Apuntes de C++ de “Estructura de Datos”. Entre otra, contiene información sobre plantillas (templates),
constructores de copia y la STL (Standard Template Library).
• Libro “Mastering UML with Rational Rose”. Wendy Boggs y Michael Boggs. Ed. Sybex, 1999. Es muy
fácil de seguir, aunque sólo cubre Rose 98. Tiene cerca de mil páginas porque contiene muchas pantallas,
aunque se repiten demasiado ciertas operaciones. Es caro.
• Libro “El Lenguaje Unificado de Modelado”. Grady Booch, James Rumbaugh e Ivar Jacobson. Ed.
Addison Wesley, 1999. A pesar de definirse en la portada como libro introductorio, es necesario tener
unos conocimientos básicos de UML antes de intentar leer este libro.
Ingeniería del Software-UML 2
Pág.
ÍNDICE.
Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Diagramas de Interacción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Diagrama de Secuencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Diagrama de Colaboración . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Diagrama de Estados . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Diagrama de Actividades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Diagrama de Clases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Diagrama de Objetos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Diagramas de Implementación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Diagrama de Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Diagrama de Despliegue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Generación de código . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
PRÓLOGO.
Este documento constituye una introducción a UML 1. Sin embargo, debido a que en la asignatura
“Laboratorio de Ingeniería del Software” se utiliza la herramienta Rational Rose, en algunos momentos se
realizan particularizaciones a dicha herramienta. También se verá una breve introducción a la metodología
“Proceso Unificado de Rational”.
A partir de los diagramas de clases y componentes es factible generar código (al menos un esqueleto
del mismo). El último tema se dedicará a la generación de código mediante Rational Rose, para lo cual se
usará C++ como lenguaje de implementación.
1
El estándar UML es muy amplio, por lo que aquí no se verán todas sus particularidades. Se recomienda consultar la
bibliografía si se desean completar los conocimientos o profundizar en algún aspecto concreto.
Ingeniería del Software-UML 3
INTRODUCCIÓN.
¿QUÉ ES UML?
Son las siglas de Lenguaje de Modela do Unificado (Unified Modeling Language). UML es un
lenguaje gráfico para visualizar, especificar, construir y documentar los artefactos de sistemas con una
componente software significativa. Como ejemplos de artefactos de un sistema tenemos el código fuente, el
diseño, los requisitos, la arquitectura y los prototipos, entre otros.
UML es un lenguaje de modelado orientado a objetos. Se debe recalcar que UML no es una
metodología, aunque proporciona técnicas que pueden ser usadas en conjunto o parcialmente en metodologías,
fundamentalmente aquellas destinadas al desarrollo orientados a objetos, como el Proceso Unificado de
Rational o Métrica V.3 (aunque Métrica V.3 es una metodología mixta que también permite el desarrollo
estructurado).
Al ser UML un lenguaje, está compuesto de una sintaxis (reglas que indican cómo ensamblar los
componentes de su vocabulario para crear expresiones) y una semántica (reglas que indican el significado de
las expresiones). Ambos aspectos serán tratados aquí.
LA IMPORTANCIA DE MODELAR .
Los sistemas, ya sean naturales o artificiales, son difíciles de comprender. Esto es debido a que en
general son bastante complejos y la mente humana sólo puede manejar 7 ±2 “elementos” de forma simultánea.
Sin embargo, es posible representar y entender un sistema usando la técnica del modelado, esto es,
construyendo modelos del sistema.
Un modelo es una simplificación de la realidad creada para comprender mejor un sistema; un modelo
es una abstracción que captura la parte esencial de los sistemas a un determinado nivel de detalle.
Los modelos:
- Ayudan a visualizar cómo es o queremos que sea un sistema.
- Permiten especificar la estructura o componentes del sistema.
- Son una guía para la construcción y mantenimiento de los sistemas.
- Permiten experimentar múltiples soluciones.
- Reducen los riesgos por errores.
- Documentan las decisiones adoptadas.
Existe una serie de principios básicos en el modelado de sistemas, entre los que destacan los
siguientes:
- Elegir el modelo más adecuado para cada sistema. Por ejemplo, si se va a realizar un desarrollo
orientado a objetos, se debería utilizar un modelado orientado a objetos.
- Cuando así convenga, el sistema se podrá ver a diferentes niveles de detalle. Para eso, se
utilizarán modelos más o menos refinados.
- Debe representar fielmente la realidad.
- Un modelo único no suele ser suficiente para modelar un sistema, siendo necesarios varios
modelos utilizando diversos puntos de vista.
- Los modelos deben ser semánticamente consistentes. Por ejemplo, si estamos modelando una casa,
los tabiques deben ser los mismos en el plano eléctrico, de la fontanería, calefacción, etc.
Ingeniería del Software-UML 4
UML utiliza modelos orientados a objetos. Un modelo orientado a objetos es una representación de un
sistema a partir de los objetos u entidades que lo constituyen, con unos atributos y operaciones asociados, que
interactúan con otros objetos para conseguir conjuntamente satisfacer los objetivos del sistema.
Existen varios tipos de modelos: gráficos, matemáticos, físicos, etc. Por ejemplo, la maqueta de un
automóvil es un modelo físico del “sistema” automóvil que podría utilizarse para estudiar su aerodinámica en
el túnel de viento.
UML es un lenguaje de modelado visual, esto es, utiliza modelos gráficos para la representación de
sistemas. Los seres humanos son criaturas visuales (de ahí el dicho “más vale una imagen que mil palabras”).
Es más fácil entender información visual que información no visual (por ejemplo, es más fácil entender un
recorrido dibujado en un mapa que entender las instrucciones en texto equivalentes). UML utiliza diagramas
para representar los modelos.
HISTORIA DE UML.
Aunque el nacimiento de los lenguajes orientados a objetos tuvo lugar en los años 70 con la aparición
de Smalltalk, fue en los 80 cuando empezó realmente su despegue y expansión.
Los métodos de modelado existentes a principios de los 80 estaban adaptados para la construcción de
programas en lenguajes pertenecientes al paradigma de la programación estructurada. Sin embargo, estos
métodos no se adaptaban correctamente al desarrollo de programas orientados a objetos.
De la experiencia acumulada, aparecieron nuevas generaciones de métodos, entre los que destacan:
- Método de Booch, de Grady Booch.
- OOSE (Object Oriented Software Engineering), de Ivar Jacobson.
- OMT (Object Modeling Technique), de James Rumbaugh.
Éstos eran métodos completos, pero cada uno de ellos tenía sus puntos fuertes y débiles. Según
evolucionaban, se iban tomando ideas los unos de los otros, pareciéndose cada vez más. Finalmente, deciden
unirse los creadores de dichos métodos (fundando “ Rational Software Corporation”) al objeto de unificar sus
métodos, naciendo UML, cuyos objetivos eran:
- Modelar sistemas, desde el concepto hasta ejecutables, utilizando técnicas orientadas a objetos.
- Válido para cualquier sistema, ya fuera pequeño, grande, crítico o complejo.
- Utilizable tanto por personas como por máquinas.
La versión actual de UML es la 1.3, que es un estándar del OMG ( Object Management Group). Se
lleva cierto tiempo trabajando ya en la versión 1.4, una revisión menor de la actual que aparecerá a corto
Ingeniería del Software-UML 5
plazo (principios del año 2001). Se espera una revisión importante del estándar hacia el año 2002, con la
publicación de la versión 2.0.
Elementos.
Hay cuatro tipos de elementos:
- Estructurales.
- De comportamiento.
- De agrupación.
- De anotación.
Los elementos estructurales representan partes materiales o conceptuales del sistema. Los elementos
estructurales principales de UML son la clase, la interfaz, la colaboración, el caso de uso, los componentes y
los nodos. Más adelante se verá su representación y significado.
Los elementos de comportamiento son las partes dinámicas de los modelos UML. Los elementos de
comportamiento básico son las interacciones (que comprende un conjunto de mensajes intercambiados entre un
conjunto de objetos, dentro de un contexto particular, para alcanzar un propósito específico) y la máquina de
estados (que especifica las secuencias de estados por las que pasa un objeto o una interacción durante su vida
en respuesta a eventos, junto con sus reacciones a estos eventos).
Mensaje Estado
Los elementos de agrupación de UML son los paquetes, y sirven para organizar otros elementos de los
modelos UML (pudiendo incluir incluso otros paquetes). Un paquete es un mecanismo conceptual de propósito
general para organizar elementos en grupos. Por ejemplo, se pueden incluir en un paquete varias clases y luego
asignar ese paquete a un componente (con lo que, realmente, lo que estamos asignado al componente son todas
las clases que el paquete incluye). Gráficamente, un paquete se visualiza como una carpeta, incluyendo su
nombre y, a veces, su contenido:
Paquete
Los elementos de anotación son partes explicativas de los modelos UML. Son comentarios que se
pueden aplicar para describir, clarificar o hacer observaciones sobre cualquier elemento de un modelo. Aunque
la mayoría de herramientas del tipo Rose permiten añadir un texto (o incluso un fichero o una dirección web)
comentando o documentando cada elemento, con las anotaciones este texto se ve de forma explícita en el
diagrama, de forma que resalta a primera vista.
Ingeniería del Software-UML 6
Aquí se escribe el
texto de la nota.
Relaciones.
Los tipos fundamentales de relaciones son los siguientes:
- Generalización.
- Asociación.
- Realización.
- Dependencia.
La relación de asociación es una relación estructural entre dos elementos. Gráficamente se muestra
como una línea que conecta ambos elementos (de forma opcional puede también acabar en punta de flecha
para indicar la dirección de navegabilidad o incluir ciertos adornos que aumentan su expresividad):
La relación de dependencia es una relación semántica entre dos elementos, en la cual un elemento
requiere la presencia de otro para su implementación o funcionamiento. Un cambio en el elemento requerido
(el independiente) puede afectar al del otro elemento (el dependiente). Se representa como una línea
discontinua entre el elemento dependiente y el independiente acabada en punta de flecha que señala al elemento
independiente (esto es, el elemento dependiente indica el elemento del que depende):
Ingeniería del Software-UML 7
Diagramas.
Los diagramas se utilizan 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 UML existen nueve tipos de
diagramas, agrupables según la siguiente clasificación:
El diagrama de casos de uso muestra actores y formas en que ést os pueden utilizar el sistema.
El diagrama de secuencia muestra cómo se mandan mensajes los actores y objetos de un sistema a lo
largo del tiempo.
El diagrama de colaboración muestra las relaciones existentes entre actores y objetos y los mensajes
enviados entre ellos.
El diagrama de estados muestra los diferentes estados por los que puede pasar un objeto, así como las
transiciones y eventos asociadas.
El diagrama de clases muestra la estructura de clases de un sistema, incluyendo las relaciones que
pudieran existir entre ellas. Es el más común de los diagramas en el modelado de sistemas orientados a
objetos.
El diagrama de objetos muestra un conjunto de objetos y sus relaciones (enla ces) en un instante
determinado. Equivale a una instancia de un diagrama de clases (o una parte del mismo) y se utiliza
generalmente para documentar estructuras de datos complejas.
El diagrama de componentes muestra cómo se organizan los elementos constit uyentes del sistema
(código fuente, ejecutables, etc.) y las dependencias existentes entre ellos.
MECANISMOS DE EXTENSIBILIDAD .
UML proporciona una serie de mecanismos de extensibilidad que permiten aumentar la capacidad
expresiva del mismo. Estos mecanismos son:
- Estereotipos.
- Valores etiquetados.
- Restricciones.
Un valor etiquetado extiende las propiedades de un bloque de construcci ón, permitiendo añadir nueva
información en la especificación de ese elemento. Los valores etiquetados se muestran encerrándolos entre
llaves. Por ejemplo, se podría mostrar el autor de una determinada clase mediante un valor etiquetado añadido
al símbolo que representa la clase: {autor = J. Macías}.
Los diagramas de casos de uso representan la funcionalidad del sistema tal como l a ven los usuarios.
En los diagramas de casos de uso se muestran las diferentes formas posibles de utilización de un sistema. Los
diagramas de casos de uso permiten visualizar el comportamiento de un sistema, de forma que los usuarios
puedan comprender cómo se utiliza ese elemento y de forma que los desarrolladores puedan implementarlo.
En un diagrama de casos de uso importa qué hace el sistema (qué proporciona), no cómo lo hace.
Los elementos principales que aparecen en los diagramas de casos de uso son:
- Actores.
- Casos de uso.
- Relaciones.
2
A los símbolos « y » se les denomina guillements y son símbolos simples. Esto significa que, por ejemplo, el símbolo
« no está compuesto de dos símbolos menor seguidos, esto es <<, sino que existe el símbolo especial «.
3
Para más información, se puede consultar el libro “Writing Effective Use Cases”, A. Cockburn, ed. Addison-Wesley
(oct., 2000).
Ingeniería del Software-UML 9
Transferir Fondos
Empleado Banca
Ingresar
Cambiar PIN
Cliente
Sistema de
Crédito
Ver Saldos
En este diagrama se pueden identificar los actores (Cliente, Empleado de Banca y Sistema de Crédito)
que son los agentes externos que interactúan con el cajero automático, los casos de uso (Transferir Fondos,
Cambiar PIN, Realizar Pago, Ver Saldos, Disponer e Ingresar) que son las funcionalidades que el cajero
proporciona y, por último, las relaciones entre actores y casos de uso (las líneas que van entre actores y casos
de uso).
Opcionalmente, se puede añadir al diagrama un rectángulo que representa los límites del sistema
representado (marca el límite entre el sistema físico objeto del modelado y los actores que interactúan con
dicho sistema), como se puede ver en el ejemplo siguiente:
Realizar Llamada
Red Telefónica
Recibir Llamada
Usuario
Usar Agenda
Teléfono móvil
Los diagramas de casos de uso son una herramienta de comunicación efectiva entre clientes y
desarrolladores. Ayudan a capturar los requerimientos del sistema (que será una cuestión básica para todo el
desarrollo posterior), para validar el diseño contra ellos, para obtener los casos de prueba (el sistema obtenido
debe proporcionar todas las funcionalidades especificadas en los casos de uso) e incluso como base para la
documentación de usuario.
Los diagramas de caso de uso se centran en la interacción entre los usuarios y los sistemas, y no en las
actividades internas que tengan lugar en dicho sistema. Son una herramienta muy general que permite
Ingeniería del Software-UML 10
especificar las reglas de un negocio 4. No están basados en la teoría de orientación a objetos y pueden usarse
tanto en procesos de desarrollo orientados a objetos como a desarrollos estructurados u otros.
La creación de los casos de uso necesita de la participación de los usuarios (expertos en e l tema a
modelar) para su construcción y validación, además de analistas. La creación de los diagramas es un proceso
de descubrimiento, que suele requerir varias sesiones.
ACTORES .
Un actor5 es un rol o conjunto homogéneo de roles que un usuario (persona o máquina) desempeña
respecto al sistema. Son, por tanto, agentes externos al sistema y que interactúan con él. Gráficamente, un
actor se simboliza mediante un hombre “de alambre”, figurando debajo de él el nombre:
Cliente
Un actor representa una clase, a la cual pueden pertenecer uno o más elementos (o, de forma
equivalente, instancias). Por ejemplo, instancias del actor cliente serían José, Luis, Fernando, etc.
Hay tres tipos principales de actores: usuarios del sistema, otros sistemas que interactúan con el
sistema que está siendo modelado y el tiempo:
- El primer tipo de actor corresponde a personas físicas o usuarios. No se deben usar nombres de
personas ya que, si tomamos por ejemplo el caso del cajero automático, una misma persona puede
desempeñar en un momento dado el rol de empleado de banca (porque sea un empleado del banco)
y en otro instante el rol de cliente (ya que además puede ser cliente del banco y usar el cajero para,
por ejemplo, sacar dinero).
- El segundo tipo de actor es otro sistema. Nuestro sistema puede interaccionar con otros sistemas,
que son externos y están fuera de nuestro control (esto es, nos vienen ya dados y es nuestro
sistema el que se debe adaptar para comunicarse con ellos).
- El tercer tipo de actor es el tiempo. El tiempo es un actor cuando el paso de un cierto tiempo
dispara algún evento en el sistema. Por ejemplo, a medianoche el sistema podría realizar un
proceso de control del estado del cajero. Debido a que el tiempo está fuera de nuestro control, es
un actor.
Representar un actor del tipo sistema externo o tiempo como un hombre de alambre puede resultar
poco claro. Una opción mejor puede ser asignar un estereotipo a los sistemas externos (por ejemplo «sistema»)
y utilizar un nuevo icono para su representación, por ejemplo la imagen de un miniordenador o un servidor. De
forma similar se puede hacer con el tiempo.
Los actores se pueden clasificar como primarios o secundarios, de pendiendo si participan en las
funciones principales del sistema (pertenecientes al ámbito del negocio, como Realizar Llamada en el caso del
4
Las reglas o procesos de negocio son procesos realizados en el seno de una cierta organización o empresa.
5
El nombre “actor” con el que se denominó a este elemento en UML no fue acertado, ya que lo que realmente
representa el elemento UML es un rol (o conjunto homogéneo de roles), y un actor del mundo real puede (y de hecho
normalmente lo hace) representar varios roles dispares.
Ingeniería del Software-UML 11
teléfono móvil) o funciones secundarias en el mismo (pertenecientes al ámbito del mantenimiento del sistema,
como copias de seguridad, arrancada y parada del sistema o administración de la base de datos).
También es posible clasificarlos como activos o pasivos, dependiendo de si inician los casos de uso o
no.
A la hora de encontrar los actores de un sistema, existen dos enfoques diferentes, ambos importantes y
legítimos, correspondientes a dos niveles de abstracción: el modelo de sistemas de información y el modelo de
negocios.
Por ejemplo, pensemos que deseamos modelar el caso de uso consistente en realizar el pedido de un
coche en un concesionario. Podríamos suponer que el actor es el vendedor o que el actor es el cliente.
En el primer caso, estamos a nivel de abstracción del modelo de sistemas de información, ya que
modelamos una solución específica organizativa y tecnológica (el vendedor es el encargado de interactuar con
el sistema).
En el segundo caso, estamos a un mayor nivel de abstracción, ya que lo que realmente modelamos es
una regla del negocio (el cliente es quién encarga el coche). Desde este punto de vista, el vendedor no es más
que un intermediario, el interface del sistema con el que interactúa el actor.
Cuando se elige el modelo de sistemas de información estamos especificando ya una enfoque definido.
Sin embargo, al usar el modelo de negocio dejamos abierta la puerta a diferentes enfoques. Por ejemplo, se
podría optar durante la fase de análisis y diseño que el cliente pudiera encargar el coche tanto personalmente a
través del vendedor, por teléfono, por correo electrónico o vía Web (simplemente, representarían diferentes
interfaces para el cliente para realizar una misma tarea: realizar el pedido de un coche).
Nota:
El uso de interfaces humano o automáticos tiene sus pros y sus contras, tal y como se puede
ver en la siguiente tabla:
Ventajas Inconvenientes
CASOS DE USO .
Un caso de uso representa una funcionalidad que el sistema proporciona o, de forma equivalente , un
caso de uso muestra una forma en la que alguien podría utilizar el sistema. Un caso de uso representa una
secuencia de transacciones en un sistema cuyo objetivo es proporcionar un resultado mensurable de valor para
el actor del sistema. Gráficamente, un caso de uso se representa mediante una elipse, con el nombre del caso
escrito dentro o debajo:
Ingresar
Para nombrar los casos de uso se utiliza un verbo o una frase que empiece por un verbo activo, que
indique el objetivo o funcionalidad del caso.
Los casos de uso pueden describir funcionalidades a diferentes niveles: sistema, subsistemas y
componentes (clases). A cualquiera de estos niveles, los casos de uso definirán el comportamiento del elemento
Ingeniería del Software-UML 12
que describen, sin revelar su estructura interna. Se debe precisar que si se utilizan casos de uso para describir
clases, los actores que participarán serán en general otras clases o subsistemas.
El nivel más importante es el que describe las funcionalidades del sistema. Pertenece al nivel de
abstracción del negocio, y es útil tanto para clientes como desarrolladores. Se les denomina casos esenciales o
abstractos. Desde este punto de vista, se puede redefinir caso de uso como “una única actividad discreta,
completa, significativa y bien definida de interés para un usuario externo que desempeña un rol o roles
específicos con relación al sistema, englobando las posibles acciones del usuario y las responsabilidades del
sistema durante el desarrollo de la actividad, descritas de una forma abstracta, independiente de la tecnología y
de la posible implementación, usando un lenguaje perteneciente al dominio de la aplicación y, por tanto,
fácilmente entendible por los usuarios”. Se debe tener en cuenta que, a este nivel, un caso de uso puede tener
una duración finita cualquiera, ya sea unos segundos, varios días o incluso meses.
A nivel de subsistemas se suelen tratar con operaciones atómicas o CRUD ( Create, Read, Update,
Delete). Este nivel suele ser poco útil para los clientes, ya que está más enfocado al diseño, centándose en las
interacciones con la base de datos en lugar de interacciones entre el actor y los sistemas. A este tipo de casos
de uso se les denomina a veces como reales, a diferencia de los anteriores (esenciales, abstractos o ideales).
Los casos de uso se deben documentar. Dicha documentación debe contener una descripción del caso
de uso y el flujo de eventos del mismo (la secuencia de acciones, incluyendo variantes, que un sistema puede
ejecutar interactuando con los actores para proporcionar la funcionalidad indicada en el caso de uso).
Opcionalmente, puede incluir precondiciones y/o postcondiciones. El texto usado en la documentación de los
casos de uso debe estar basado en el lenguaje del negocio a modelar. No se recomienda detallar excesivamente
ni utilizar pseudocódigo para especificar el flujo de eventos, ya que podría restringir las soluciones a tomar.
Las secciones que podrán aparecer en un caso de uso son, por tanto:
- Descripción. Describe, generalmente de forma breve, lo que hace el caso de uso.
- Precondiciones. Son las condiciones que se deben cumplir antes de poder utilizar el caso de uso.
- Postcondiciones. Son las condiciones que se cumplirán después de haber finalizado la ejecución
del caso de uso.
- Flujo de eventos primario (o base) y alternativo(s). El flujo de eventos describe, paso a paso, lo
que sucede en el caso de uso (no cómo sucede). El flujo primario describe la situación normal
(debe ser además el primer flujo descrito al crearlo). El flujo o flujos alternativos documentan qué
ocurre en situaciones variantes o anormales (por ejemplo, que el cliente no dispusiera de suficiente
saldo). Para especificar flujos de eventos se puede, además de texto, usar otras técnicas, como los
diagramas de actividad o de estado.
Si se utiliza texto para especificar el flujo de eventos, se recomienda seguir el estilo del siguiente
ejemplo, que representa el flujo de eventos para el caso de uso de “obtención de ayuda para un problema
específico” de una empresa de ventas:
RELACIONES .
Hay cuatro tipos de relaciones que pueden aparecer en un diagrama de casos de uso.
Relación de comunicación.
Es el tipo más normal de relaciones y tiene lugar entre un caso de uso y un actor. Gráficamente es una
línea, a la que se puede añadir una punta de flecha para indicar quién inicia la comunicación.
Por ejemplo:
Realizar Pago
Cliente Sistema de
Crédito
En este caso, el actor “Cliente” se comunica con el caso de uso “Realizar Pago”, siendo el actor quien
inicia la comunicación. Además, el caso de uso “Realizar Pago” se comunica con el actor “Sistema de
Crédito”.
Todos los casos de uso deben ser iniciados por un actor (a excepción de los casos de uso que
extienden el comportamiento o están incluidos en otro caso de uso, tal y como se verá más adelante).
Relación de inclusión6.
La relación de inclusión en un caso de uso “A” de caso de uso “B” (esto es, la flecha va de “A” a
“B”) indica que el caso de uso “A” contiene el comportamiento indicado por “B”. El lugar o lugares donde
dicho comportamiento se incluye debe especificarse en el flujo de eventos de “A”.
La relación de inclusión se muestra gráficamente como una relación de dependencia con el estereotipo
«include». Por ejemplo:
«include»
Disponer
Autentificar Cliente
«include»
Realizar Pago
En este fragmento se puede ver que tanto el caso de uso “Disponer” como “Realizar Pago” incluyen el
caso de uso “Autentificar Cliente”. Esta factorización permite especificar de una sola vez un comportamiento
común a varios casos de uso.
6
En versiones anteriores de UML a esta relación se le denominaba de uso (uses), sin embargo su nombre se cambio
por la de incluye (include) ya que el anterior nombre daba a entender una semántica que no se correspondía con la
real.
Ingeniería del Software-UML 14
Las relaciones de inclusión también se pueden utilizar para detallar un caso de uso complejo que
proporcione varias subfuncionalidades, de manera que visualmente se puedan apreciar de una forma más fácil
en qué consiste dicho caso, sin tener que consultar la descripción del mismo.
La relación de inclusión indica que un caso de uso va a usar siempre la funcionalidad pro porcionada
por otro caso.
Relación de extensión.
Una relación de extensión de un caso de uso “A” a un caso de uso “B” indica que comportamiento del
caso de uso “B” puede ser incrementado con el comportamiento del caso de uso “A”, sujeto a determinadas
condiciones, que pueden ser especificadas en la extensión o en el caso de uso.
La relación de inclusión se muestra gráficamente como una relación de dependencia con el estereotipo
«extend». Por ejemplo:
Relación de generalización.
Entre actores:
La relación de generalización entre actores se utiliza cuando varios actores tienen características
comunes. Gráficamente se muestra como una relación de generalización que va del actor especializado al
genérico. Para los usuarios del teléfono móvil podríamos representar, por ejemplo:
Usuario
Una generalización de un actor “A” (descendiente) a un actor “B” (ancestro) indica que una instancia
de “A” puede comunicarse con los mismos casos de uso que un actor “B”. Para el caso del ejemplo, un
“Usuario Tarjeta” (o un “Usuario Contrato”) podría comunicarse con los mismos casos de uso que un
“Usuario” y, posiblemente, con otros particulares a él (por ejemplo, un “Usuario Tarjeta” podría comunicarse
con el caso de uso “Recarga Tarjeta”).
Ingeniería del Software-UML 15
Se deben de usar las relaciones de generalizació n entre actores cuando algunos actores tengan en
común parte de sus comportamientos o cuando interese mostrar explícitamente que cualquier especialización
de un tipo de actor actúa de igual forma.
La relación de generalización entre c asos de uso se utiliza para indicar que un caso de uso es un
refinamiento de otro. Por ejemplo:
7
Para modelar el modo en que las tareas se llevan a cabo en una empresa se podrían utilizar diagramas de flujo de
trabajo (workflow diagram).
Ingeniería del Software-UML 16
- Se debe evitar crear los casos de uso basándose exclusivamente en la interfaz del sistema de
información que ya existiera, si se diera esta situación, ya que en vez de las reglas del negocio (el
qué) podemos estar dando directamente una solución basada en el sistema existente, que pudiera
no ser lo suficientemente buena o flexible.
- Se debe cuidar la granularidad. Los casos de uso abstracto deben capturar lo esencial y no
intentar detallar demasiado, porque esta situación hace caer en el cómo. Sin embargo, una
pequeña descomposición de los casos puede hacerlos más fáciles de comprender y simplificar su
diseño.
Tomar Productos
Aportar Datos Cliente
«include» Aportar Forma Pago
«include»
«include»
1 n «extend»
Tomar Pedido
Vendedor
Pedir Catálogo
1 n
Proporcionar Crédito El catálogo se
Supervisor enviará al servir el
pedido.
Notas:
- El supervisor es una especialización de vendedor. El supervisor es el único que puede
proporcionar crédito, pero también puede tomar pedidos como cualquier otro vendedor, ya que es
una especialización de éste.
- En el ejemplo se puede ver una forma de utilización de las notas.
- Se ha añadido la multiplicidad en las relaciones de comunicación.
- La condición para la extensión “Pedir Catálogo” estará definida en el caso de uso “Tomar
Pedido” (no se ha mostrado en el diagrama).
- Véase que se ha optado por modelar a nivel de sistema de información (aparece el actor
“vendedor” y no el actor “cliente”).
Nota: El flujo de eventos primario del caso de uso “Validar usuario” sería:
- Descripción: Permite al cliente obtener una cierta cantidad de dinero en efectivo del cajero
automático.
- Flujos alternativos:
- En el paso 2, el usuario cancela la operación. Se pasa al paso 7.
- En el paso 5, el usuario indica que la cantidad es errónea. Se vuelve al paso 2.
- En el paso 6, si no es posible proporcionar la cantidad requerida, se indica y se vuelve al paso
2.
- Postcondición: La operación, si finaliza con éxito, queda reflejada en la cuenta del usuario.
DIAGRAMAS DE INTERACCIÓN.
Definiciones previas.
Objeto: Es una entidad con límites definidos e identidad propia que encapsula un estado y un
comportamiento. Un objeto es una instancia de una clase.
Atributo: Característica que describe el rango de valores que una instancia de una clase puede
almacenar.
Ingeniería del Software-UML 18
Operación: Es un servicio que puede ser solicitado a un objeto para que se comporte de una
determinada forma.
Un objeto se representa gráficamente como un rectángulo, dentro del cual se incluye, subrayado, el
nombre del objeto (empezando por letra minúscula), o la clase (empezando por letra mayúscula) a la que
pertenece precedida de dos puntos, o ambos:
Por ejemplo:
También puede incluirse una sección en la que se mues tren los valores de uno o más atributos, tal y
como se puede ver en el ejemplo siguiente:
Oscar : Persona
Nombre: String = “Oscar”
dni: Integer = 3102427
telefono = 91 555 00 00
Los diagramas de interacción muestran cómo cooperan (interaccionan) un conjunto de objetos para
realizar alguna tarea determinada. Modelan, por tanto, aspectos dinámicos del sistema. Un diagrama de
interacción consta de un conjunto de objetos y sus relaciones (ya sea de forma implícita o explícita), así como
de los mensajes que se envían entre ellos.
Una de las aplicaciones más importantes de los diagramas de interacción consiste en el modelado de
escenarios. Un escenario es una secuencia específica de acciones entre objetos que permite mostrar un
comportamiento. Un escenario es, por tanto, una instancia de un flujo de eventos particular de un caso de uso.
Varios diagramas de interacción representando escenarios pertenecientes a distintos flujos de eventos de un
mismo caso de uso (por ejemplo, flujo principal, flujo alternativo 1, flujo alternativo 2, etc.) se suelen agrupar
en un paquete. Cada diagrama de interacción que represente un escenario debe tener al menos un objeto actor
iniciante, que es el estímulo externo que ejecuta alguna funcionalidad. Este objeto actor será una instancia de
un actor perteneciente al diagrama de casos de uso al que pertenece el flujo de eventos.
A la hora de construir un diagrama de interacción, es necesario encontrar los objetos que participan, a
los que se añadirán a continuación los mensajes que se envían. Existen varias técnicas para encontrar objetos.
Una de ellas consiste en analizar los sustantivos que aparezcan en los flujos de eventos o en escenarios
específicos. En general, estos sustantivos se corresponderán con actores, atributos u objetos (serán objetos si
exhiben un comportamiento). Sin embargo, esta técnica no permite descubrir todos los objetos. Habrá
posiblemente que añadir objetos cuya tarea sea controlar 8 a los otros objetos (controlan el desarrollo de los
acontecimientos). También puede ser necesario añadir objetos de entrada/salida, como formularios e informes,
que realizan la tarea de interface entre el usuario y el sistema.
En Rose, un objeto se puede calificar (a través de sus especificaciones) como persistentes ( persistent),
estático (static) o transitorio (transient):
- Persistente: Aquel cuya vida continúa aunque el programa haya terminado. Cuando se vuelva a
ejecutar el programa, el estado del objeto dependerá del estado que tuviera al terminar la ejecución
anterior. Para que esto sea posible, debe ser guardado en un fichero o una base de datos
(almacenamiento permanente) al terminar una ejecución y recuperado al empezar la siguiente.
- Estático: Es aquel que reside en memoria hasta que el programa termina. Esto es debido a que se
trata de un objeto compartido por varios hilos de control o procesos.
- Transitorio: Aquel que permanece en memoria por un espacio de tiempo limitado (por ejemplo,
durante el tiempo o parte del tiempo en que se desarrolla una determinada tarea o flujo de
eventos).
El estándar también proporciona un símbolo para múltiples instancias de un objeto. Esto permite
representar en los diagramas de interacción agrupaciones de objetos como, por ejemplo, listas de objetos. En
general, los mensajes que se mandan a las agrupaciones de objetos constan de una búsqueda más una
operación que se requiere al objeto (o subconjunto de objetos) encontrado. La notación es la siguiente (este
icono sólo puede aparecer en el diagrama de colaboración):
: Persona
Para modelar los mensajes, Rose permite especificar cinco semánticas diferentes de sincronización de
mensajes:
- Simple: El mensaje se ejecuta en un hilo simple de control, por lo que el objeto al que va destinado el
mensaje siempre lo aceptará y de forma inmediata. Es la opción por defecto. Gráficamente se
representa como:
8
Este tipo de objetos, denominados objetos activos, se pueden mostrar en UML regruesando sus bordes para
diferenciarlos del resto de objetos, los pasivos.
Ingeniería del Software-UML 20
- Síncrono: El objeto cliente manda el mensaje y espera hasta que el objeto al que va destinado acepta
el mensaje. Gráficamente se representa como:
- Tiempo límite (timeout): El cliente manda el mensaje y espera como máximo una determinada
cantidad de tiempo. Si el objeto destino no está disponible para recibir el mensaje durante ese periodo,
el cliente abandona el mensaje. Gráficamente se representa como:
- Asíncrono: El cliente manda el mensaje y continua sin esperar confirmación de si el mensaje ha sido
recibido. Gráficamente se representa como:
Rose también permite especificar la frecuencia de los mensajes, calificándolos como aperiódicos
(mandados en un instante cualquiera de forma única o sin una periodicidad; es la opción por defecto) o
periódicos (aquellos que son enviados a intervalos regulares).
Se debe tener en cuenta que, al poner un mensaje en un diagrama de interacción, se está asignando una
responsabilidad al objeto que lo recibe. Por ejemplo, si en un diagrama de interacción se representa un mensaje
de un objeto a al objeto b, es responsabilidad del objeto b aceptar el mensaje y obrar en consecuencia, para lo
cual deberá disponer del método adecuado. Supongamos, por ejemplo, que a manda el mensaje
imprimir(hola.txt) al objeto b; el objeto b debe tener una operación, que normalmente se implementará con un
método denominado imprimir, que trate dicho mensaje (en este caso el comportamiento de b podría consistir
en imprimir el fichero hola.txt que se le ha pasado como parámetro).
Los diagramas de interacción constituyen una piedra angular en el diseño, ya que a través de ellos los
desarrolladores pueden determinar las clases que necesitan (aquellas a las que pertenecen los objetos que
aparecen en ellos), las relaciones entre clases y las operaciones y responsabilidades de cada clase.
Para que el diseño sea consistente, todo objeto de un diagrama de interacción deberá ser mapeado en
algún momento a una clase del diagrama de clases, así como todo mensaje deberá ser mapeado a una
operación (método) de la clase que recibe el mensaje. Además, la persistencia indicada en los diagramas de
interacción debe ser compatible con la persistencia indicada en los diagramas de clase, debiéndose cumplir en
Rose lo siguiente:
- Si la clase se define como persistente en el diagrama de clases, un objeto de dicha clase podrá
calificarse como transitorio, estático o persistente en el diagrama de interacción.
- Si la clase se define como transitoria en el diagrama de clases, un objeto de dicha clase podrá
calificarse como estático o transitorio en el diagrama de interacción.
En Rose, es posible documentar en las especificaciones de un caso de uso los diagramas relacionados
con dicho caso (ya sean de interacción, estado, actividad o clases).
Al ser semánticamente equivalentes los diagramas de secuencia y los de colaboración, es posible pasar
de uno a otro automáticamente. Por ejemplo, en Rose basta crear uno de ellos y pulsando la tecla [F5]
generará el otro.
Ingeniería del Software-UML 21
DIAGRAMA DE SECUENCIA.
Un diagrama de secuencia es un tipo de diagrama de interacción en el cual se destaca el tiempo: los
mensajes entre objetos vienen ordenados explícitamente por el instante en que se envían. Consta de dos ejes.
Generalmente, el eje vertical es el eje del tiempo, transcurriendo éste de arriba a abajo. En el otro eje se
muestran los objetos que participan en la interacción, siendo el primero de ellos el actor que inicia la ejecución
de la secuencia modelada.
De cada objeto parte una línea discon tinua, llamada línea de la vida, que representa la vida del objeto
durante la interacción. Si el objeto existe durante toda la interacción, éste aparecerá en el eje horizontal y su
línea llegará hasta el final del diagrama de secuencia.
Los mensajes parten de la línea de vida del objeto que lo envía hasta la línea de vida del objeto al que
va destinado (excepto en el caso del mensaje de creación, como se verá más adelante). Cada mensaje lleva un
número de secuencia creciente con el tiempo y el nombre de la operación requerida, así como posibles
argumentos que pueden utilizarse como valores de entrada y/o salida.
Usualmente, no se especifica una graduación en el eje del tiempo, aunque podría hacerse para
interacciones que modelen escenarios en tiempo real.
Por ejemplo, vamos a modelar un escenario que muestre una instancia del flujo de eventos primario
del caso de uso “Validar usuario”, en el cual el cliente Luis se identifica ante el cajero automático con su
número secreto (el 4567):
Nota: Se recuerda que el flujo de eventos primario del caso de uso “Validar usuario” era:
Un objeto se crea mediante un mensaje de estereotipo «create» que apunta al objeto que se crea. Un
objeto se destruye mediante un mensaje de estereotipo «destroy», dando finalizada la línea de vida con un
aspa. En este diagrama de secuencia simplificado se pueden ver varios ejemplos de creación y destrucción de
objetos:
objetoA objetoB
juan : Cliente
«destroy»
«create
objetoC
«destroy»
«create
objetoE
Apréciese que objetoA y objetoB existen ya cuando empieza el diagrama, aunque objetoB es
destruido, por lo que su línea de la vida está interrumpida en el punto de su destrucción. Por otro lado,
objetoC es creado y destruido durante la interacción, mientras que objetoE es creado y continua existiendo al
final del diagrama (al igual que objetoA).
Opcionalmente, se puede mostrar en los diagramas de secuencia el foco de control, que es un pequeño
rectángulo puesto sobre la línea de la vida que indica qué objeto tiene el control en cada momento (esto es, el
tiempo durante el cual está realizando una acción directa o indirectamente). Véase, por ejemplo, el siguiente
fragmento simplificado:
1: mensaje1
2: mensaje2
Ingeniería del Software-UML 23
En este ejemplo, objeto1 tiene el control al empezar. En un momento determinado, manda un mensaje
(mensaje1) al objeto2 para requerirle una cierta operación. A partir de ese momento, objeto2 tiene también el
control. Para realizar la operación, objeto2 necesita un servicio de objeto3, para lo cual le envía el mensaje2,
teniendo también control el objeto3 desde que recibe el mensaje hasta que finaliza el servicio requerido. De
igual forma, el control de objeto2 finaliza al terminar el servicio que le había requerido objeto1.
Téngase en cuenta que para el caso de un sólo hilo de ejecución, o cuando se debe esperar la
terminación de la operación solicitada por un mensaje para continuar, el que un objeto tenga el foco de control
no significa que se esté “ejecutando” realmente código de dicho objeto durante todo el tiempo de control (ya
que puede estar esperando que termine alguna operación que haya requerido de algún otro objeto).
Aunque, en principio, los diagramas de secuencia están pensados para mostrar un único escenario,
Rose permite mediante los Scritps modelar varios flujos simultáneamente, aunque no se debe abusar de esta
posibilidad, ya que puede complicar en demasía el diagrama. Un ejemplo de script sería:
objeto1 objeto2
ELSE
2: mensaje2
Aunque Rose no lo soporta, UML permite añadir la condición delante del mensaje (como por ejemplo
[x>0] mensaje, que indica que se mandará el mensaje sólo si la condición se cumple, esto es, si x es mayor
que cero). También permite desdoblar la línea de vida de un objeto en varias para mostrar flujos alternativos.
REFINAMIENTO .
Los diagramas de secuencia permiten mostrar escenarios de forma que sean comprensibles tanto por
clientes como por desarrolladores.
Sin embargo, una vez que los clientes h an dado su visto bueno a los mismos, se suelen refinar
añadiendo detalles de diseño que serán útiles a los desarrolladores. Por ejemplo, en el diagrama de secuencia
visto anteriormente para validar usuario se debería de refinar e incluir un objeto que fuera el que controlara
todo el proceso en vez de ser un objeto : Pantalla Cajero el que se encargue de la mayoría del control. Esto es
así porque el objeto : Pantalla Cajero es un interface y no conviene que los interfaces se encarguen del control
ya que se volverían muy complicados y heterogéneos, y serían muy sensibles a los cambios.
De forma similar, se suelen crear objetos que manejen transacciones, de forma que se separe la lógica
de la aplicación de la lógica de la base de datos. De esta forma, si la lógica de la base de datos cambia, sólo es
necesario realizar cambios en la clase encargada de las transacciones. Además, este tipo de clases suelen ser
fácilmente reutilizables.
Ingeniería del Software-UML 24
DIAGRAMA DE COLABORACIÓN.
Un diagrama de colaboración es un diagrama que muestra una interacción en el cual se destaca la
organización estructural de los objetos que envían y reciben mensajes. Un diagrama de colaboración muestra
los objetos que intervienen en una relación, los mensajes que se intercambian y las relaciones de comunicación
que hay entre ellos (para que un objeto pueda comunicarse con otro debe existir algún tipo de enlace o link
entre ellos).
2: leerNumTarjeta( )
1: aceptarTarjeta( )
lector : Lector
Tarjeta
luis : Cliente
5: introducirPin(4567)
3: inicializarPantalla()
4: pedirPIN()
7: mostrarOperaciones()
6: verificarPIN(4567)
: Pantalla cuentaDeLuis :
Cajero Cuenta
Apréciese que, aunque aquí también aparece el orden de los mensajes, no es fácil seguir la secuencia
de los mismos. Sin embargo se ve claramente qué objetos participan y las relaciones que existen entre ellos, lo
que les hace muy útiles para los desarrolladores. Estos diagramas permiten, por ejemplo, valorar el impacto
que supondría un cambio en una clase.
Hay una diferencia significativa entre los diagramas de secuencia y los de colaboración, y es que en
los de colaboración se pueden añadir explícitamente flujos de datos. Esto se hace mostrando al lado del
mensaje afectado un circulo al que se añade una flecha indicando la dirección del flujo. Si la dirección del
flujo coincide con la del mensaje, se trata de un argumento de entrada. Si no coincide, se trata de un valor de
retorno.
Como ejemplo, aquí se muestra un flujo de datos correspondientes a argumentos de entrada del
mensajeA que objeto1 envía a objeto2:
1: mensajeA()
objeto1 objeto2
En general, sólo se utiliza esta técnica cuando el flujo de datos es grande, como por eje mplo cuando se
pasa una lista.
Ingeniería del Software-UML 25
En los diagramas de colaboración también se pueden asociar estereotipos a los roles de los enlaces,
como por ejemplo «local», que es una restricción que especifica que el objeto al que califica es visible por ser
una variable local al objeto que manda el mensaje. También se pueden añadir restricciones a los objetos que
indiquen su persistencia: {new} si son creados durante la interacción, {destroy} si son destruidos o {transient}
si son creados y destruidos durante la interacción. Por ejemplo:
1: create()
2: mensajeA()
3: destroy()
objeto1 objeto2 {transient}
L
En este caso, objeto2 es accesible a objeto1 por ser local a objeto1 (nótese que en Rose, en vez de
aparecer el estereotipo «local», lo que aparece es una L en el extremo del enlace). El objeto2 es además
transitorio, siendo creado y destruido en la interacción (como de hecho se puede comprobar por los mensajes
que se le envían).
DIAGRAMA DE ESTADOS.
Un diagrama de estados muestra el ciclo de vida de un objeto (aunque también se puede utilizar para
sistemas o subsistemas) desde el momento en que el objeto es creado al momento de su destrucción. Describe
todas las secuencias de estados y acciones por las que un objeto puede pasar durante su vida como reacción a
distintos eventos (como pueden ser los mensajes o señales).
Un estado es una situación particular en la que se exhibe un comportamiento determinado y que está
caracterizado por el valor de uno o más atributos y/o por las relaciones con otros objetos. El estado en que se
encuentre un objeto será por tanto dependiente de su historia anterior.
Por ejemplo, un objeto de tipo fax podría encontrarse en los estados inactivo, transmitiendo o
recibiendo, y en cada uno de estos estados tendría un comportamiento diferente. Un evento, como por ejemplo
pulsar la tecla “Parar” cuando se encuentra en el estado transmitiendo, haría que pasara al estado inactivo.
Los diagramas de estado sólo se suelen realizar para objetos (clases) que tienen un comportamiento
dinámico significativo, esto es, para aquellos que poseen un conjunto significativo de estados. Esto sucede con
los objetos reactivos, que son aquellos cuyo comportamiento viene dirigido por los eventos que recibe. En
estos casos, los diagramas de estado resultan de gran utilidad para los desarrolladores.
Para encontrar clases con un comportamiento dinámico significativo, se puede buscar en primer lugar
aquellos objetos que se comporten de forma diferente según los valores de sus atributos, siendo candidatos,
por ejemplo, las clases que tengan un atributo llamado estado.
También se deben analizar las clases que participen en relaciones en las que aparezca en número cero
en la multiplicidad. Esto significa que dicha relación es opcional y puede que el comportamiento en ese caso
sea muy diferente. Por ejemplo, en una relación entre persona y compañía para la que trabaja, si un objeto
persona tiene una relación con una o más compañías significará que es un empleado. Sin embargo, si no tiene
ninguna relación, podría estar parado, jubilado o incapacitado.
Ingeniería del Software-UML 26
En un diagrama de estados aparecen uno o más estados relacionados entre sí por transiciones. Las
transiciones, en general, serán ocasionadas por algún evento. Por ejemplo, este podría ser el diagrama de
estados de un objeto de la clase Curso:
Abierto
cancelar
Cancelado
fin periodo matrícula
cancelar
Cerrado
fin cuatrimestre
Completado
ESTADO.
Un estado una situación en la vida de un objeto durante la cual se satisface alguna condición, se
realiza alguna actividad o se espera algún evento.
NombreEstado
Dentro del estado (o adjunto en el extremo sup erior izquierdo en ciertas ocasiones) se puede escribir el
nombre del estado, aunque es opcional y se pueden utilizar estados anónimos.
Mientras un objeto está en un estado particular, puede realizar cero, una o más acciones internas. En
este contexto, una acción es una tarea que tiene lugar mientras un objeto se encuentra en un determinado
estado. Estas acciones se muestran en una sección debajo del nombre del estado, con el formato
etiquetaDeAcción/expresiónDeAcción. La etiqueta de acción identifica las circunstancias o eventos bajo los
cuales la expresión de la acción será invocada.
Existen algunas etiquetas de acción reservadas para propósitos especiales y que no pueden ser
utilizadas como nombres de eventos. Estas son:
entry: Indica que la tarea se realiza cuando el objeto entra en dicho estado. Se considera una acción no
interrumpible.
exit: Indica que la tarea se realiza cuando el objeto abandona el estado. Se considera una acción no
interrumpible.
do: Indica que la tarea se realiza mientras el objeto permanezca en el estado en que se encuentra o
hasta que termine dicha tarea. Se considera una acción interrumpible. Dicho de otra forma, cuando un
objeto está en un estado que contiene una acción etiquetada con do, realiza dicha acción (después de
realizar la acción de entrada si la hubiera) hasta que ésta termina o hasta que se abandona dicho
estado por la llegada de un evento adecuado.
Ingeniería del Software-UML 27
, siendo la lista de parámetros y la condición de guarda (condición que se debe satisfacer para que se produzca
la acción si se recibe el evento) opcionales.
Por ejemplo (nótese que Rose añade a las etiquetas no predefinidas la palabra event):
LeyendoPassword
Como se puede ver, el estado LeyendoPassword contiene una serie de acciones. En primer lugar, al
entrar (entry) se eliminaría el eco para evitar que los caracteres tecleados sean visibles. Después, si se recibe
un evento carácter (esto es, el usuario introduce un carácter c) se realiza el tratamiento de dicho carácter (esto
es, se añadirá a una cadena para ir formando el password que se teclee). Si el usuario pulsara la tecla definida
como ayuda, el objeto recibirá el evento Ayuda. En ese caso, el objeto manda el mensaje mostrarAyuda al
objeto ayuda, con el argumento password (esto es, se requiere al objeto ayuda que muestre la ayuda sobre el
password). Al salir de este estado (exit) se vuelve a poner el eco para que se puedan ver los caracteres
tecleados. La forma de salir de este estado no se ha especificado, pero puede suponerse que esto ocurre al
pulsar el usuario la tecla [enter] (este sería el evento que produciría el cambio de estado).
En este ejemplo se ha visto cómo especific ar desde un objeto el envío de un mensaje. La sintaxis
general es:
^objeto.mensaje(argumentos)
Estados especiales.
Estado inicial. Es un pseudoestado que representa el estado en que se encuentra un objeto cuando es creado
(inicio de la vida del mismo). Debe aparecer obligatoriamente uno y sólo uno en todo diagrama de estados.
Gráficamente se representa:
Estado final. Es un pseudoestado que indica la destrucción del objeto (finalización de la vida del mismo). Es
opcional y se pueden añadir varios estados de fin para simplificar el diagrama y evitar el cruce de líneas.
Gráficamente se representa:
Ingeniería del Software-UML 28
TRANSICIÓN .
Una transición es el paso de un estado a otro. Se muestra gráficamente como una flecha que va del
estado origen al estado destino:
EstadoOrigen
EstadoDestino
Este movimiento puede ser reflexivo, es decir, el estado origen y el estado destino pueden coincidir, tal
y como se muestra a continuación:
Las transiciones pueden incluir especificaciones que indiquen cuándo ocurre la trans ición o qué
acciones se llevarán durante la transición. En caso de no indicarse evento, significa que la transición ocurre
inmediatamente después de satisfechas las posibles acciones entry, do y exit del estado. El formato general de
estas especificaciones es:
Un evento es un suceso que ocurre y que puede causar la transición de un estado a otro. La condición
de guarda, si se especifica, debe cumplirse para que la transición sea posible. La acción es un comportamiento
no interrumpible que ocurre como parte de la transición. Nótese que no siempre es posible sustituir esta acción
por una acción interna entry en el estado destino, ya que otras transiciones al estado destino pueden requerir
otras acciones (o ninguna).
paro Movimiento
entry/ motorOn
exit/ motorOff
avance[ noTocandoMuro ]
Si partimos del robot en estado inactivo y pulsamos el botón de avance (evento avance), el robot se
pone en movimiento (acción entry) siempre y cuando no esté tocando el muro (condición de guarda de la
transición). Si estamos en movimiento y pulsamos el botón de paro (evento paro) el robot se para (acción exit)
y pasa al estado inactivo. Si, por otro lado, estando en movimiento se activa el sensor de muro, el robot se
para y además suena un pitido de alarma, pasando al estado inactivo. En el estado inactivo puede recibir el
Ingeniería del Software-UML 29
evento girar que haga que gire un número determinado de grados. En este último caso se trata de una
transición reflexiva.
ESTADOS ANIDADOS .
Un estado puede estar compuesto por uno o más subestados. Estos subestados pueden ser disjuntos o,
en el caso de que existan varias regiones o barras de sincronización, concurrentes. A su vez, los subestados
pueden estar compuestos por otros subestados y así sucesivamente.
EstadoCompuestoConSubestadosDisjunto
Subestado1 Subestado2
En este caso se ha añadido un estado de inicio y de terminación dentro del estado compuesto, aunque
no es necesario si las transiciones, que entran o salen al estado, llegan o parten de los subestados.
Una de las ventajas de los estados compuestos es que, si todos sus subestados responden a una misma
transición, sólo hace falta ponerla una vez en el estado superior. Esto hace que se reduzcan el número de
líneas en el diagrama, haciéndolo más sencillo. Si tomamos el ejemplo del diagrama de estados de un curso
dado al inicio, podemos definir un nuevo estado, denominado Activo, que englobe a los subestados Abierto y
Cerrado, y agrupar sus transiciones cancelar en una única transición que parte del estado Activo:
Activo
Abierto
fin cuatrimestre
cancelar
Completado Cancelado
Hay veces que, después de salir de un estado compuesto, interesa volver al mismo subestado en el que
se estaba cuando se salió. Para modelar esta posibilidad, se utilizan estados con memoria. Estos estados se
identifican porque en la esquina inferior izquierda tienen una letra H (de History) dentro de una circunferencia.
Ingeniería del Software-UML 30
Por ejemplo:
Activo
Abierto
dimite profesor
Pendiente de cancelación
H
cancelar
fin cuatrimestre
cancelar
Completado Cancelado
En este diagrama, existe un nuevo est ado al que se accede desde el estado Activo cuando dimite el
profesor del curso. Si se asigna un nuevo profesor es posible volver al subestado anterior ( Abierto o Cerrado)
debido a que el superestado tiene historia.
En caso de que los subestados sean a su vez estados compuestos, es también posible volver al último
subestado pertenezca al nivel que pertenezca. Para ello, el superestado que contiene a todos los subestados
debe estar marcado con H* en vez de H.
Para modelar estados compuestos concurrentes se utilizan regiones concurrentes. Estas reguiones se
separan por lineas de puntos en el superestado. Alternativamente a las regiones concurrentes, es posible
utilizar barras de sincronización, como las que se utilizan en el diagrama de actividades, tal y como se verá.
Ejemplo:
Recibiendo clase
Incompleto
hecha hecha
Práctica1 Práctica2
terminado Aprobado
Trabajo
aprobado
Examen
suspendido
Suspenso
Ingeniería del Software-UML 31
En este ejemplo, el estado Incompleto (que a su vez es un subestado de Recibiendo clase) está
compuesto por tres subestados, cada uno de ellos en una región concurrente. Además, el primer subestado está
compuesto por otros dos subestados, en este caso disjuntos ( Práctica1 y Práctica2).
EstadoCompuesto
SIMPLIFICACIÓN DE TRANSICIONES .
Cuando varias transiciones son disparadas por un mismo evento pero con diferente condición de
guarda, es posible utilizar una simplificación para su dibujo. Por ejemplo:
ev [cg1]
Origen Destino1
ev [cg2]
Destino1
ev [cg3]
Destino1
[cg1]
Destino1
Origen ev [cg2]
Destino1
[cg3]
Destino1
Ingeniería del Software-UML 32
DIAGRAMA DE ACTIVIDAD9.
Los diagramas de actividad permiten modelar el comportamiento de un sistema o alguno de sus
elementos, mostrando la secuencia de actividades o pasos que tienen lugar para la obtención de un resultado o
la consecución de un determinado objetivo. Opcionalmente, permite mostrar los flujos de información
(objetos) producidos como resultado de una actividad y que serán utilizados posiblemente como entrada por la
actividad siguiente.
Los diagramas de actividad son útiles para describir flujos de evento en los casos de uso, las
actividades que tienen lugar entre un conjunto de objetos (clases) y las operaciones o métodos de las clases.
Es interesante comparar las diferencias entre los diagramas de estados y actividades. La siguiente
tabla es un resumen de ellas:
Énfasis en el orden procedimental y/o flujo de objetos Énfasis en la reacción al entorno (control por
(control procedimental). eventos).
Veamos a continuación un ejemplo de diagrama de acti vidad, que muestra los diferentes pasos o
actividades y el orden en que se deben realizar para obtener un disco de sistema (MS-DOS):
Formatear
Pistas
Grabar Boot
Crear FAT
Crear
Directorio Raíz
Grabar Fich.
Sistema
9
Actualmente, los diagramas de actividad de UML son un caso especial de una máquina de estados, por lo que
comparte ciertas características comunes con los diagramas de estado. Sin embargo, para evitar confusiones, se ha
evitado intencionadamente el uso de la palabra estado al hablar de las actividades, aunque realmente una actividad es
un estado de acción.
Ingeniería del Software-UML 33
El elemento fundamental de los diagramas de actividad son las actividades. Una actividad representa
la ejecución de una tarea o misión en un flujo de trabajo o la ejecución de una sentencia en un procedimiento,
dependiendo del elemento cuyo comportamiento se esté modelando.
Las actividades pueden describirse usando lenguaje natural, aunque cuando el diagrama mode la
operaciones de una clase suele utilizarse pseudocódigo o incluso el lenguaje de programación en que se vaya a
realizar el desarrollo.
Las actividades se relacionan unas con otras mediante transiciones, que indican el orden en que se
deben de realizar las actividades, empezando desde el punto de inicio del diagrama hasta llegar a un punto
final del mismo.
Una transición se dispara cuando termina de realizarse la actividad de la que parte. También es
posible añadir condiciones de guarda a las transiciones. Esto permite realizar decisiones o bifurcaciones
basadas en las condiciones de las guardas, tal y como muestra el ejemplo siguiente:
Leer PIN
Verificar PIN
[ incorrecto ]
[ correcto ]
Nótese que se utiliza un rombo para simbolizar el punto de decisión y el origen de las bifurcaciones.
Las condiciones de guarda de una decisión deben ser mutuamente excluyentes, y se permite la
condición especial [else] que se cumple cuando no se cumple ninguna de las otras.
Una actividad puede estar compuesta de un conjunto de subactividades, que suelen ser model adas
utilizando un diagrama de actividad propio. Una actividad compuesta no está concluida hasta que no han
concluido sus subactividades. Para indicar que una actividad contiene subactividades, se añade un pequeño
símbolo de composición en su esquina inferior derecha, tal y como se puede ver en el siguiente ejemplo:
Actividad Compuesta
Ingeniería del Software-UML 34
Conseguir
ingredientes
Batir
Freir
Como se puede ver, la transición que sigue a la actividad Conseguir ingredientes se divide por medio
de una barra de sincronización en dos transiciones que desembocan en las actividades Calentar aceite y
Cascar huevos, que pueden ser realizadas de forma concurrente. Por otro lado, la transición que desemboca en
la actividad Freir parte de una barra de sincronización a la cual llegan dos transiciones. Este es un punto de
sincronización que indica que no se disparará la transición saliente de la barra hasta que no se hayan
disparado las transiciones entrantes (esto es, hasta que no hayan concluido las actividades de las transiciones
entrantes: Calentar aceite y Cascar huevos).
Ingeniería del Software-UML 35
En los diagramas de actividades también se pue den representar calles (swimlanes: calles en el sentido
de las diversas calles paralelas en las que se divide una piscina olímpica). Las calles son elementos
organizativos que permiten asignar las responsabilidades de las acciones a unidades organizacionales de un
negocio o a clases. Por ejemplo, en el siguiente diagrama se modela una compra por correo:
Solicitar
pedido
Verificar
pedido
Reunir pedido
Enviar pedido
Recoger
pedido
Obsérvese, por ejemplo, que el cliente es el encargado de realizar las actividades Solicitar pedido y
Recoger pedido.
Ingeniería del Software-UML 36
Los diagramas de actividad permiten también mostrar el flujo de información (objetos) entre
actividades, significando un compromiso tanto por parte de la actividad que debe generarla como por la
actividad que debe aceptarla como entrada. Para ello, se dibuja una línea discontinua terminada en flecha que
va desde la actividad que genera como salida al objeto, y otra línea similar que va desde el objeto a la
actividad que sigue y que recibe dicho objeto como entrada. Frecuentemente, un mismo objeto se repite como
entrada y salida en diversas actividades sucesivas, actividades que posiblemente irán modificando el estado del
objeto. En este caso se suele añadir al nombre del objeto el estado en que se encuentra entre corchetes.
Por ejemplo:
Solicitar
pedido
: Pedido [realizado]
Verificar
pedido
: Pedido [verificado]
Reunir pedido
: Pedido [completado]
Enviar pedido
: Pedido [enviado]
Recoger
pedido
ICONOS DE CONTROL .
Los iconos de control son un mecanismo que, aun no siendo imprescindibles para la construcción de
los diagramas de actividad, resulta una conveniencia que puede ser útil para añadir cierta clase de información
en las transacciones. Existen dos iconos de control, el de envío de señal y el de receptor de señal.
Ingeniería del Software-UML 37
El icono de envío de señal equivale a una transacción que envía una señal. Su símbolo es:
El icono de recepción de señal equivale a un estado de espera, esto es, se produce una espera hasta
que se recibe una señal que dispara la transacción. Su símbolo es:
Optativamente, se puede añadir una línea discontinua acabada en flecha que vaya al objeto que recibe
la señal o que parta desde el que la envía (puede ser el mismo). Por ejemplo:
Levantarse
Encender
caferera
Café hecho
Beber café
DIAGRAMA DE CLASES.
Los diagramas de clases se utilizan para mostrar la estructura estática del sistema modelado. Pueden
contener clases, interfaces, paquetes, relaciones e incluso instancias, como objetos o enlaces. Los diagramas de
clases son una potente herramienta de diseño, ayudando los desarrolladores a planificar y establecer la
arquitectura y estructura del sistema y subsistemas antes de escribir ningún código. Esto permite asegurar que
el sistema está bien diseñado desde el principio. Los diagramas de clases son usados prácticamente en la
totalidad de sistemas en que se utiliza UML para su modelado.
Para sistemas no triviales, se suele usar más de un diagrama de clases. Cuando se utilizan varios
diagramas, cada uno no tiene necesariamente que representar divisiones del modelo subyacente, sino que se
utilizarán según convenga, pudiendo una misma clase aparecer en diagramas diferentes para representar
distintas vistas del modelo.
Ingeniería del Software-UML 38
CLASES.
Las clases son los componentes fundamentales de los diagramas de clases. La notación general para
una clase es un rectángulo dividido en tres secciones, mostrando la primera el nombre de la clase (y
opcionalmente otra información que afecte a la clase), la siguiente los atributos y la última las operaciones.
Por ejemplo:
Punto
coordenadaX
coordenadaY
mostrar()
ocultar()
posicionX()
posicionY()
Tanto la sección de los atributos como la de las operaciones pueden no mostrarse, en cuyo caso
tampoco se mostrará la línea que las separa. Tampoco es necesario visualizar todos y cada uno de los
atributos y operaciones, lo cual puede ser útil para remarcar qué atributos u operaciones son interesantes en
una determinada vista. En este caso, conviene añadir puntos suspensivos (...) al final de la sección de la que se
hayan suprimido atributos u operaciones.
Opcionalmente, se pueden añadir más secciones para indicar otra información, como
responsabilidades de la clase, excepciones que puede generar, eventos que maneja, etc. Tanto éstas como las
secciones de atributos y operaciones pueden contener en primer lugar un nombre que indique la sección de que
se trata. Por ejemplo:
Reservas
operaciones
confirmar()
cancelar()
cambiar()
responsabilidades
facturar clientes sin reserva
ajustarse a habitaciones libres
excepciones
tarjeta de crédito no válida
Rose permite especificar la visibilidad de cada clase. La visibilidad puede ser pública, protegida o
privada (-), con los significados usuales. También es posible otras visibilidades dependientes del lenguaje,
como por ejemplo la visibilidad de implementación o paquete ( implementation) en el caso de C++ que
equivale a una visibilidad pública para el resto de clases definidas en el mismo paquete y privada para las
definidas fuera. También permite especificar otras propiedades, como por ejemplo si los objetos son
persistentes, estáticos o transitorios.
Ingeniería del Software-UML 39
Sección de nombre.
El nombre de la clase se debe poner centrado y en negrita 10, y empezando por letra mayúscula. En
caso de que la clase sea abstracta, el nombre se pondrá además en cursiva. Los nombres de clase deben ser
únicos en su entorno, pudiendo coincidir sus nombres si están definidos en paquetes distintos (ya que sería otro
entorno). Cuando sea necesario, se puede preceder al nombre de la clase por el nombre del paquete donde se
ha definido, como por ejemplo Utilidades::Visualizador.
En caso de especificar un estereotipo para la clase, éste se pondrá encima del nombre de la clase.
También es posible sustituir el rectángulo por un icono asociado a dicho estereotipo o poner dicho icono en el
extremo superior derecho de la sección.
- «control»: Indica que la clase es una clase de control que se dedica a labores de coordinación.
Estas clases son fácilmente reconocibles porque de ellas suelen partir muchos mensajes a otras
clases. Su icono es el siguiente:
En esta sección también se pueden añadir, debajo del nombre, valores etiquetados con alguna
información relativa a la clase. En el siguiente ejemplo se muestra la clase EntradaMaterial, con el
estereotipo «boundary» y valores etiquetados que indican su autor y estado:
«boundary»
EntradaMaterial
{autor = Eva,
estado = comprobado}
Sección de atributos.
10
Rose no lo visualiza en negrita.
Ingeniería del Software-UML 40
La visibilidad puede ser pública (+), protegida (#), privada (-) o, según el lenguaje, implementación.
Rose permite mostrar la visibilidad mediante los signos o, de forma optativa, con un icono:
El nombre del atributo se escribirá con minúsculas, y a continuación se pondrá entre corchetes su
multiplicidad (siendo optativo para el caso habitual de multiplicidad 1). Cuando la multiplicidad es mayor que
uno se puede pensar que equivale a definir un array.
La multiplicidad en UML se indica como uno o más intervalos enteros (en el caso de múltiples
intervalos, se separarán por comas). Cada intervalo tiene el formato límiteInferior..límiteSuperior (cuando el
límite inferior es igual que el superior basta con poner simplemente el número). Para indicar un límite
indefinido, se utiliza el símbolo asterisco (*), aunque Rose utiliza en este caso la letra ene (n).
Si un atributo tiene como multiplicidad 0..1, significa que dicho atributo podrá contener un valor o
ninguno (esto es, puede tener un valor nulo, que significa la ausencia de valor). Imagínese que una estación
meteorológica recoge la temperatura a medio día todos los días. Si un día, por cualquier razón, esto no es
posible, el valor de dicho atributo será nulo (ningún valor), que es distinto de 0.0, que sería una temperatura
de 0º. Si tuviéramos que hallar la media de temperaturas, las temperaturas con valor nulo no serían usadas (no
pueden sumar en el numerador ni tampoco cuentan para el denominador).
El tipo será uno de los existentes en el lenguaje de desarrollo, igual que la forma de expresar el valor
inicial. El valor inicial es optativo (en cuyo caso no se incluye el signo igual), pero el tipo es obligatorio,
aunque puede no visualizarse.
La cadena de propiedades es optativa. Por ejemplo, {frozen} indica que un atributo no es modificable.
Cuando la clase dispone de un atributo(s) “clave”, esto es, que el valor de dicho atributo(s) identifica
de forma unívoca a cada objeto de dicha clase, se puede indicar subrayándolo(s).
Los atributos derivados, esto es, los atributos cuyo valor se calcula a partir de otros atributos de la
clase, se marcan con una barra inclinada (/) delante del nombre. Aunque el uso de atributos derivados se debe
evitar, pueden ser recomendables en algunos casos por cuestiones de eficacia (tiempo de ejecución).
Los atributos estáticos, esto es, atributos cuyo valor es compartido por todas las instancias de una
clase, se marcan con el símbolo de dólar ($) delante del nombre.
Rose también permite indicar el modo de almacenamiento del atributo, esto es, si será almacenado
por valor o por referencia.
Ejemplos:
Habitacion Punto
Apréciese en la clase Habitación que el atributo area es derivado, ya que puede calcularse
multiplicando el valor de los atributos largo y ancho.
Nótese también que en la clase Punto no se han visualizado el tipo de sus atributos, aunque sí estarán
definidos, y sólo se han mostrado parte de los atributos, por lo que se han añadido punto suspensivos para
indicarlo.
Sección de operaciones.
En la sección de operaciones se muestran todas o parte de las operaciones que la clase proporciona,
alineadas a la izquierda y utilizando la siguiente sintaxis:
La visibilidad puede ser pública (+), protegida (#), privada (-) o, según el lenguaje, implementación,
de forma similar a la visibilidad de los atributos. Es obligatorio especificarla, aunque puede no visualizarse.
El nombre de la operación se escribirá en minúsculas. En caso de que sea una operación abstracta
(recurso utilizado para implementar polimorfismo), se escribirá en cursiva.
En caso de existir parámetros, estos vendrán separados p or comas y siguiendo la siguiente sintaxis
para cada parámetro:
El nombre indica el nombre del parámetro formal y se escribirá en minúsculas. Después se indica el
tipo del parámetro (que será dependiente del lenguaje) y, en caso de que existiera, el valor por defecto.
A continuación se indica el tipo que retorna la operación (que será dependiente del lenguaje), pudiendo
suprimirse si la operación no devuelve ningún valor (procedimiento).
Por último, se podrá indicar una cadena de propiedades. Aquí se podría indicar, por ejemplo, si una
operación es secuencial {concurrency=sequential} o concurrente {concurrency=concurrent}.
Es posible añadir una nota a una operación para indicar, por ejemplo, su algoritmo o código. Rose
también permite para cada operación especificar, entre otras, las precondiciones, postcondiciones, su
semántica, la cantidad (absoluta o relativa) de memoria necesaria para la operación y el tiempo (absoluto o
relativo) que precisará su ejecución.
- Auxiliares. Operaciones necesarias para que la clase pueda realizar su trabajo, pero que no son
visibles desde el exterior. Este tipo de operaciones aparece como mensajes reflexivos en los
diagramas de interacción (generalmente, en los de bajo nivel).
Por ejemplo:
Rectangulo
-p[1..2]: tPunto
«constructor»
+Rectangulo(p1: tPunto, p2: tPunto)
«query»
+area(): double
+perimetro(): double
...
«update»
#mover(delta: tPunto)
#escalar(ratio: double=2.0)
...
Nótese que se ha escrito el nombre del constructor empezando por mayúsculas. Esto ha sido así
porque, presuponiendo que esta clase se implementará en C++, el nombre del constructor debe ser igual que el
nombre de la clase.
Las clases deben estar equilibradas tanto en el número de operaciones como en el de los atributos. Si
una clase tiene muy pocos atributos u operaciones, puede significar (aunque no necesariamente) que se ha
llegado a una descomposición demasiado grande y que sería mejor que fuera absorbida por otra clase con
responsabilidades coherentes. Si una clase tiene demasiados atributos u operaciones, puede significar (aunque
no necesariamente) que tiene demasiadas responsabilidades y que es mejor dividirla en dos o más clases más
sencillas.
RELACIONES .
Una relación es una conexión semántica entre elementos (en nuestro caso, clases o, de forma más
general, entre clasificadores). Existen cuatro tipos principales de relaciones en UML:
- Generalización: Es una relación de especialización.
- Asociación: Es una relación estructural. Existen dos subtipos, la agregación y la composición.
- Realización: Es una relación contractual, en la cual un clasificador especifica un contrato (por
ejemplo, un interface) que otro clasificador garantiza que cumplirá.
- Dependencia: Es una relación de uso.
Desde un punto de vista amplio, la generalización, asociación y realización son también relaciones de
dependencia. Sin embargo, debido a sus características particulares, UML las creó como relaciones
específicas. Conviene modelar antes estas relaciones, ya que las que no se ajusten a ellas serán relaciones de
dependencia.
Hay varias formas de encontrar o diseñar relaciones. Por ejemplo, si en un diagrama de interacción un
objeto a manda un mensaje a un objeto b, habrá una relación entre ellos (típicamente una asociación o una
Ingeniería del Software-UML 43
dependencia). También se deben examinar posibles relaciones todo-parte (que posiblemente se podrán modelar
como relaciones de composición o agregación). Las generalizaciones de pueden crear mediante un proceso
descendente (de arriba a abajo, de la clase más general a la más particular) o ascendente (de abajo a arriba, de
las más particulares a las más generales).
Generalización.
La generalización es una relación taxonómica 11 entre el objeto más general (el padre o superclase) y el
más específico (el hijo o clase descendiente). Gráficamente, se especifica como una línea acabada en flecha
vacía que va del elemento más particular (el hijo) al más general (el padre):
ClasePadre
ClaseHija
La generalización se utiliza para modelar la herencia en los lenguajes orientados a objetos. Una de las
características de la herencia es que permite simplificar la construcción de clases relacionadas, ya que gracias
a ella es posible agrupar las características comunes de un conjunto de clases en una clase padre (superclase)
y hacer que todas ellas hereden de la superclase.
Todos los lenguajes orientados a objetos permiten la herencia simple (una clase puede descender a lo
sumo de otra), aunque algunos lenguajes, como C++, permiten la herencia múltiple (una clase puede descender
de varias clases padre). Aunque la descendencia múltiple puede ser muy conveniente en algunos casos, no se
debe abusar de ella (ya que puede resultar compleja su utilización).
También se debe cuidar el esquema de herencia. Un esquema con demasiados niveles (más de cuatro o
cinco) es usualmente demasiado complicado de entender; un esquema de sólo dos niveles y muy ancho no suele
estar aprovechando la potencia de la herencia (ya que, posiblemente, sería posible extraer características
comunes entre algunas clases del segundo nivel que permitiera la creación de un nuevo nivel).
Por ejemplo:
Vehículo
Véase que en este ejemplo las clases Vehículo, Terrestre y Aéreo son abstractas, luego no se puede
instanciar ningún objeto de ellas.
11
Clasificación, en el sentido de clasificación de “especies” en ancestras y descendientes.
Ingeniería del Software-UML 44
Si el lenguaje dispusiera de herencia múltiple, podríamos crear clases descendientes de varias clases
padre, como en el siguiente ejemplo:
Terrestre Marítimo
Anfibio
La relación de generalización también puede darse entre paquetes, indicando que un paquete es una
especialización de otro. Los paquetes descendientes heredan los elementos públicos y protegidos del paquete
ancestro, redefiniendo generalmente algunas clases y definiendo otras nuevas. Por ejemplo:
GUI12
WindowsGUI XWindowGUI
Asociación.
Las asociaciones modelan relaciones estructurales entre clases. Una asociación se representa
gráficamente como una línea que conecta las clases relacionadas:
Compañía Persona
Esta asociación significa que la clase Compañía puede acceder a los atributos y operaciones públicas
de la clase Persona y que, de forma similar, la clase Persona puede acceder a los atributos y operaciones
públicas de la clase Compañía.
También se puede restringir la navegabilidad de la asociación, añadiendo una flecha que indique el
sentido de dicha asociación:
Compañía Persona
En este caso, Compañía puede acceder a los atributos y operaciones públicas de la clase Persona,
pero Persona no puede acceder a Compañía.
12
Interface gráfica de usuario.
Ingeniería del Software-UML 45
Una clase puede relacionarse consigo misma, es decir, pueden modelarse asociaciones reflexivas:
Persona
Esta asociación reflexiva podría modelar, por ejemplo, la relación “es familiar directo de”.
Se pueden añadir varios adornos y otros elementos a las as ociaciones que aumentan su expresividad o
completan o restringen su significado:
- Nombre de la asociación. Es un nombre descriptivo que indica la naturaleza de la asociación.
Opcionalmente se puede añadir un pequeño triángulo que indique el sentido en que se debe
interpretar. Por ejemplo:
Trabaja para
Compañía Persona
En este ejemplo, estamos expresando que las personas trabajan para las compañías. Téngase
en cuenta que el sentido del nombre de la asociación no restringe la navegabilidad.
Es posible indicar el estereotipo de la asociación encima del nombre, siendo también posible
indicar una cadena de propiedades a la derecha del nombre o debajo.
- Roles. Se puede indicar el rol que desempeña una o ambas clases en la asociación. Por ejemplo:
Compañía Persona
patronal empleado
- Multiplicidad. Se puede indicar cuántas instancias (objetos) de una clase podrán estar asociados a
una instancia (objeto) de la otra. Por ejemplo:
Compañía Persona
0..* 1..*
En este caso, para una compañía podrán trabajar una o más personas, y una persona podrá
trabajar en cero (que representaría el caso de estar desempleada) o más compañías.
- Calificador. Es un atributo que califica una asociación. Dado un objeto origen y un valor
determinado para el calificador, se obtendrá un objeto destino (si la multiplicidad del destino es a
lo más uno) o un conjunto de objetos destino (si la multiplicidad del destino es muchos). Por
ejemplo:
titular
Banco Nº cuenta: int Persona
0..* 0..1
Ingeniería del Software-UML 46
En este ejemplo, dado un banco y un número de cuenta, obtendremos una persona (el titular de
la cuenta). Téngase en cuenta que el calificador pertenece a la asociación y no es un atributo ni
del banco ni de la persona.
Es significativo el extremo de la asociación en el que se pone el calificador. Por ejemplo, si el
nº de cuenta lo representáramos nada más que con los dígitos finales (eliminando los dígitos
iniciales, que son los que especifican el banco), tal y como está el ejemplo, para un banco y un
número de cuenta obtendríamos un solo titular. Pero si pusiéramos el nº de cuenta en el extremo
de Persona, dado un titular y un nº de cuenta obtendríamos uno o más bancos.
El uso de cualificadores restringe el entorno de la asociación y es útil, por ejemplo, para
realizar búsquedas.
- Orden. Si la multiplicidad es mayor que uno, los elementos relacionados por la asociación pueden
estar ordenados o no. Se utiliza {ordered} para indicar que dichos elementos se encuentran
ordenados. Por ejemplo:
paciente
Lista Médico Persona
{ordered}
- Xor-asociación. Se utiliza esta restricción para indicar que sólo una de las posibles asociaciones
modeladas en el diagrama de clases puede ser instanciada en un momento dato para una
determinado objeto. Se representa gráficamente como una línea de puntos que conecta dos o más
asociaciones a la que se le añade la restricción {xor}. Por ejemplo:
Persona
Cuenta {xor}
Compañía
Aquí estamos indicando que una cuenta puede estar a nombre de una compañía o de una
persona, pero no simultáneamente de ambas. Esto es, un objeto : Cuenta puede estar relacionado
(enlazado) con un objeto : Persona o con un objeto : Compañía, pero no con un objeto : Persona y
un objeto : Compañía a la vez.
- Clase asociación. Designa a una asociación que tiene propiedades de clase, tales como atributos,
operaciones y/o otras asociaciones. Siempre es representada junto a la asociación a la que
corresponde, y unida a ella mediante una línea discontinua. Ya que clase y asociación forman un
todo, el nombre de ambas es igual, pudiéndose especificarse en cualquiera de ellas o en ambas.
Por ejemplo:
0..* 1..*
Compañía Persona
patronal empleado
Trabajo
jefe
fechaContrato
salario 0..1
trabajador
0..*
dirige
Ingeniería del Software-UML 47
Nótese que Trabajo, al pertenecer a la asociación, está ligado tanto a Compañía como a
Persona, y es ese conjunto el que tiene significado. Véase que este diagrama permite modelar que
una persona p1 fuera jefe de otra persona p2 en una compañía c1, y que simultáneamente p2 fuera
jefe de p1 en una compañía c2.
Hasta ahora se han visto asociaciones binarias, pero las asociaciones se pueden dar entre cualquier
número de clases. Tal caso se representa gráficamente como un rombo que está unido por una línea continua a
todas las clases incluidas en la asociación. Por ejemplo:
Temporada
0..*
0..* 0..*
Equipo Jugador
Ficha
sueldo
clausulaRescision
En este ejemplo se modela una asociación denominada Ficha (que además tiene una clase asociación)
entre las clases Temporada, Jugador y Equipo.
Agregación y composición.
Estas relaciones son un tipo especial de asociación. En una relación de asociación, las clases
participantes tienen una relación de igual a igual, mientras que en la agregación y la composición la relación
es de todo-parte. Esto es, una clase forma parte o es un componente, en algún sentido, de otra.
Simplificando se puede decir que, internamente, una clase todo contendrá a una clase parte agregada
por referencia, mientras que a una clase parte compuesta la contendrá por valor.
La agregación se representa como una asociación con un rombo vacío en el lado de la clase todo. Por
ejemplo:
1 4
Coche Rueda
Aquí se ha mostrado que un coche (el todo) t iene cuatro ruedas (la parte). Se ha modelado como una
agregación porque la rueda puede existir antes que el coche como entidad propia o incluso después (se
desguaza el coche y de dejan las ruedas) e incluso se puede cambiar alguna de las ruedas de un coche a otro.
Ingeniería del Software-UML 48
La composición se representa como una asociación con un rombo lleno en el lado de la clase todo. Por
ejemplo:
1 0..*
Formulario Botón
Aquí se ha mostrado que un formulario (el todo) puede contener cero o más botones (la parte). Un
botón sólo puede existir dentro de un formulario, por lo que la vida del botón estará restringida a la vida del
formulario que lo posee. Un botón pertenece a un y sólo un formulario.
1 contiene 3..*
Poligono Punto
{ordered}
1
PropiedadesGraficas
1
color
textura
focosIluminacion
Realización.
Una realización es una relación semántica entre clasificadores, en la cual un clasificador especifica un
contrato que otro clasificador garantiza que cumplirá. Generalmente se emplea la realización para especificar
una relación entre una interfaz y la clase o componente que implementa las operaciones especificadas en dicha
interfaz.
Una interface es un clasificador que especifica una serie de operaciones, pero que no proporciona
ninguna implementación (ni tiene atributos). Es equivalente a una clase abstracta que sólo tiene operaciones
abstractas. Un ejemplo de interface sería el RS-232 (suele ser el estándar para puertos serie). El estándar
especifica operaciones como el envío y recepción de caracteres, que podrán ser implementados por un chip o
tarjeta (que son los que realizan dicha interface).
Gráficamente, una interface se muestra como una clase con el estereotipo «interface» y sus
operaciones, o en forma resumida como un círculo y debajo el nombre del interface:
«interface»
Mensurable
Para indicar que una clase realiza una interfaz, se muestra una línea discontinua acabada en flecha
vacía que va de la clase que implementa el interfaz a la interfaz.
Ingeniería del Software-UML 49
Por ejemplo:
Saco
...
peso(): double
volumen(): double
... «interface»
Mensurable
...
peso(): double
volumen(): double
...
En este caso, se indica que tanto Saco como Automovil “realizan” el interface Mensurable, es decir,
ambas implementan las operaciones indicadas en el interface.
En el caso de usar la notación resumida, se unirá el interface a la clase que lo implementa por una
línea continua. Por ejemplo:
Saco
Mensurable
Automóvil
Mensurable
Cuando una clase realiza un interface, debe implementar todas las operaciones indicadas en dicha
interface y, posiblemente, otras exclusivas de la clase.
Varias clases pueden satisfacer un interface (como en el ejemplo anterior), y una clase puede
satisfacer varios interfaces. Por ejemplo:
Furgoneta Mensurable
Alquilable
Las interfaces pueden evitar en ciertos casos el uso de herencia múltiple. Son muy útiles para
independizar la implementación de sistemas o utilidades de los servicios u operaciones que proporcionan (esto
es, se puede cambiar la implementación sin que sea necesario modificar las llamadas, ya que no se ha
Ingeniería del Software-UML 50
modificado el interface), fomentando la reutilización. Los interfaces son soportados por lenguajes como Java o
Corba.
Otra de las posibilidades de los interfaces consiste en limitar el acceso en las asociaciones. Por
ejemplo, sea el siguiente interface:
«interface»
Empleado
nombre()
fechaNacimiento()
dni()
numeroHijos()
Compañía Persona
: Empleado
Esto evitaría, por ejemplo, que la Compañía pudiera acceder a métodos de la clase Persona que no
fueran de su incumbencia para el tipo de relación Compañía-Persona (como sería el caso, suponiendo que la
clase Persona lo implementara, del método perteneceGrupoRiesgoSida(): bool, que sí sería de incumbencia
en una relación Médico-Persona).
Dependencia.
Una dependencia es una relación entre un elemento dependient e (el cliente) y un elemento
independiente (el suministrador del servicio requerido). El elemento dependiente (cliente) requiere conocer al
elemento independiente (suministrador) y que éste esté presente. Las dependencias se usan para modelar
relaciones en la cual un cambio en el elemento independiente (el suministrador) puede requerir cambios en el
elemento dependiente (el cliente).
Cliente Servidor
En este caso, la clase Cliente (dependiente) dependerá de servicios proporcionados por la clase
Servidor (independiente), y un cambio en la clase Servidor puede ocasionar que la clase Cliente necesite ser
adaptada. Un cambio en la clase Cliente no tiene ningún efecto sobre la clase Servidor, ya que esta última es
independiente de la primera (no la necesita).
Para que la clase dependiente tenga acceso a la clase independiente, la clase independiente debe tener
visibilidad global, ser pasada como parámetro a una operación o ser instanciada como variable local en una
operación de la clase dependiente.
Ingeniería del Software-UML 51
Cuando una clase usa los servicios de otra a través de un interface, también se modela como
dependencia (depende del interface, un cambio en el interface requeriría un cambio en la clase dependiente).
Por ejemplo:
ClaseImplementadoraInterface ClaseDependiente
Interface
Las relaciones de dependencia también se utilizan para mostrar la dependencia entre paquetes. Tal y
como se dijo, las clases se suelen agrupar en paquetes. Para agrupar las clases en paquetes, se pueden utilizar
varios criterios. Un criterio puede ser el agrupar las clases por estereotipos (en este caso habría un paquete
para las clases frontera, otro para las de control y otro para las de entidad). También es posible agrupar las
clases por su funcionalidad (podría haber un paquete con clases que se encargaran del control de acceso, otras
de la gestión informes, otra de errores, etc.). Como los paquetes pueden contener a su vez otros paquetes, una
tercera posibilidad consiste en agrupar las clases por funcionalidades y dentro de cada grupo de funcionalidad,
volver a agrupar por estereotipo.
Una relación de dependencia entre un paquete A y un paquete B indica que alguna clase del paquete A
tiene una relación unidireccional con alguna clase del paquete B y, por tanto, el paquete A necesita tener
acceso al paquete B. Las relaciones de dependencia entre paquetes deben ser calificadas con el estereotipo
«access» o «import». Con ambos estereotipos se tiene acceso a los elementos públicos del paquete
independiente, pero con «access» es necesario preceder dichos elementos por el nombre del paquete que los
contiene mientras que con «import» no (en este caso, es necesario que ningún nombre de un elemento del
paquete dependiente coincida con un nombre de elemento del paquete independiente). Por ejemplo:
«access»
A B
Los paquetes contenidos en otros paquetes pueden acceder a todos los elementos del paquete que los
contiene. Sin embargo, las dependencias no son transitivas, tal y como se muestra en el siguiente ejemplo:
B
«import «import
A » » D
C
Ingeniería del Software-UML 52
Clases parametrizadas.
Una clase parametrizada o plantilla (template) es un descriptor de una clase con uno o más parámetros
formales. Una clase parametrizada define una familia de clases: cada clase se especifica ligando los
parámetros formales de la clase parametrizada a valores reales. Una plantilla no es utilizable directamente (es
decir, no se puede instanciar ningún objeto de la misma) por tener parámetros libres. Gráficamente, una clase
parametrizada se muestra como una clase a la que se añade un recuadro en línea discontinua en la parte
superior derecha donde se indican sus parámetros formales:
ListaParámetros
NombreClase
Las clases parametrizadas suelen utilizarse para crear contenedores, siendo el parámetro el tipo de
elemento que almacenará dicho contenedor. También puede recibir valores, como por ejemplo un número
entero.
Un ejemplo de clase parametrizada (del tipo contenedor) sería una plantilla de pila. Esta plantilla,
además de tener el tipo del elemento a almacenar como parámetro, podrá recibir un valor entero que indique el
máximo número de elemento de la pila (100 por defecto). Para instanciar una clase a partir de la clase
parametrizada, se utilizará una dependencia estereotipada como «bind» (ligar), tal como se muestra en el
ejemplo:
tElem, max:int=100
Pila
«bind» (persona,200)
PilaPersonas
También es posible indicar directamente los parámetros entre ángulos en la clase instanciada. Por
ejemplo:
Pila<persona>
Nótese que en este caso no se ha especificado el número máximo de elementos, luego la pila tendrá
100 que es el número que se le ha dado por defecto. Si quisiéramos dar expresamente el valor, quedaría:
Pila<persona,100>
Ingeniería del Software-UML 53
UTILIDADES .
Las utilidades son un agrupamiento de variables y procedimientos globales en forma de una
declaración de clase. Es un artificio que facilita el diseño y programación. Una clase utilidad se modela con el
estereotipo «utility», tal como se puede ver en el siguiente ejemplo:
«utility»
UtilidadesMatemáticas
sin(double): double
random(): double
...
Otro ejemplo sería una utilidad de operaciones estadísticas, como la media, la mediana, la desviación,
etc. Al definirse como utilidad, se podrían utilizar dichas operaciones directamente por cualquier clase
(visibilidad global).
Las utilidades pueden estar parametrizadas, utilizándose una notación similar a las clases
parametrizadas.
TIPOS .
Los tipos se utilizan para especifica r un dominio de objetos junto con las operaciones aplicables a
dichos objetos, sin definir ni la implementación física de esos objetos ni métodos. Un tipo se representa como
una clase con el estereotipo «type»:
«type»
MiTipoDeDatos
Esta notación permite modelar los tipos predefinidos del lenguaje o crear tipos nuevos. Para que el
nuevo tipo sea utilizable, es necesario crear una clase que proporcione métodos para todas las operaciones del
tipo. La relación sería una realización:
«type»
MiTipoDeDatosImplementado
MiTipoDeDatos
DIAGRAMA DE OBJETOS.
Un diagrama de objetos es una instancia de un diagrama de clases. Es una instantánea de un sistema
en la que se detalla el estado del mismo en ese momento: objetos, valores significativos de los atributos y
enlaces entre objetos. Un diagrama de clases indica lo que puede ser el sistema; un diagrama de objetos
representa la situación del sistema en un momento determinado (se utilizan instantes significativos o
prototípicos).
Los diagramas de objetos se utilizan, generalmente, para visualizar, especificar y documentar mod elos
estructurales, esto es, estructuras de objetos cuya complejidad aconseje dibujar un diagrama que sirva para
una mejor comprensión del modelo.
Ingeniería del Software-UML 54
Compañía
0..n
Dpto
0..n 1..n
Persona
: Compañía
: Persona
: Persona : Persona
Nótese que los enlaces son instancias de las relaciones del diag rama de clases, esto es, relaciones que
se dan en un momento dado, por lo cual no puede aparecer ninguna multiplicidad en ellas. También se han
incluido los valores del atributo nombre de los objetos de la clase Dpto para facilitar su entendimiento.
También es posible especificar el estado en que se encuentra el objeto. Por ejemplo, el siguiente
diagrama muestra un objeto de la clase Robot que se encuentra moviéndose (estado movimiento), así como el
mundo (entorno) que ha identificado y la relación entre elementos identificados:
: Robot [movimiento]
: Mundo
Nótese que el objeto a1 es un área rectangular (habitación) formada por tres muros y una puerta, y
que cada uno de los elementos constituyentes está relacionado con su adyacente (por ejemplo, el muro m1
limita con la puerta p1 y con el muro m3).
Como en los diagramas de clases también se pueden mostrar objetos, un diagrama de clases que sólo
contenga instancias de clases, esto es, objetos, se le puede denominar diagrama de objetos. Este caso sucede,
por ejemplo, en Rose: no hay un diagrama de objetos como tal, por lo que se debe utilizar un diagrama de
clases para representar un diagrama de objetos.
DIAGRAMAS DE IMPLEMENTACIÓN.
Los diagramas de implementación muestran aspectos relativos a la implementación, incluyend o la
estructura del código fuente y similares (diagrama de componentes) y la estructura de implementación en
tiempo de ejecución (diagrama de despliegue).
DIAGRAMAS DE COMPONENTES.
Un diagrama de componentes se utiliza para modelar los componentes de un sistema y mostrar las
dependencias entre ellos.
Ingeniería del Software-UML 56
Hay una gran diferencia entre clases y componentes. Las clases son “componentes lógicos”, mientras
que los componentes tienen significado físico. Antes de poder generar código, las clases deben ser mapeadas a
componentes (esto es, las clases residen o son implementadas en componentes), y estos componentes serán los
que contengan su código fuente.
Nombre
Dentro del componente se especifica su nombre y/o su tipo y, opcionalmente, una cadena de
propiedades que indiquen, por ejemplo, su versión, autor, estado, etc. También se puede mostrar dentro de un
componente las clases o paquetes que residan en él, o incluso otros componentes.
Un componente puede depender de otro. En este caso existe una relación de dependencia entre ellos,
tal y como se puede ver en el siguiente ejemplo:
programa.exe programa.pas
Nótese que el programa ejecutable ( programa.exe) depende del programa fuente (programa.pas).
Esta es una dependencia de compilación: para generar programa.exe necesitamos programa.pas.
Tal y como se dijo, los componentes deben tener interfaces bien definidos. Esto permite que los
componentes puedan ser reemplazados (por ejemplo, por componentes más eficaces) y reutilizados fácilmente,
posibilitando la construcción de componentes complejos utilizando componentes más simples. Se puede
expresar explícitamente que un componente depende de un interface realizado por otro componente, tal y como
se muestra a continuación:
B.dll A.exe
Esto podría modelar, por ejemplo, un ejecutable A.exe que requiere de algún servicio proporcionado
por la dll (Dinamic Link Library) B.dll. No habría ningún problema en cambiar la dll por otra más moderna
que fuera, por ejemplo, más eficaz, ya que, al accederse a ella a través de un interface, no habría que realizar
ninguna modificación en los ejecutables.
Ingeniería del Software-UML 57
Rose proporciona para los componentes algunos estereotipos estándar con iconos asociados, tal y
como se muestra a continuación:
- Especificación y cuerpo de subprograma. Los subprogramas son colecciones de rutinas (no
contienen definiciones de clases), tales como funciones o procedimientos. Las especificaciones
constituyen el interface del componente (la definición de las funciones; en C++ sería el fichero .h)
y el cuerpo la implementación (la implementación de las funciones; en C++ sería el fichero .cpp).
Sus representaciones gráficas son:
Programa principal
- Especificación y cuerpo de paquete. Los paquetes contienen las clases. Las especificaciones
constituyen el interface del componente (la definición de las clases; en C++ sería el fichero .h) y el
cuerpo la implementación (la implementación de los métodos de las clases; en C++ sería el fichero
.cpp). En C++ se pueden asociar varias clases a un componente, mientras que en Java cada clase
debe asociarse a un componente individual. Sus representaciones gráficas son:
- Especificación y cuerpo de tarea. Representa paquetes que tienen hilos independientes de control.
Normalmente, un fichero ejecutable se representa como una especificación de tarea con extensión
.exe. Sus representaciones gráficas son:
.exe
.hlp a.dll
principal.exe
principal.cpp
b.h
a.h
c.h b.cpp
a.cpp
c.cpp
Ingeniería del Software-UML 59
Este tipo de diagrama muestra el orden en que se deben compilar los ficheros, a qué otros
componentes afectaría el cambio de uno de ellos y qué se debería recompilar. Téngase en cuenta que en los
diagramas que muestran la secuencia de compilación no deben aparecer referencias circulares, ya que sería
imposible realizar dicha compilación.
A la hora de asociar clases a componentes, si éstas se han agrupado en paquetes, se suelen asociar
dichos paquetes a los componentes. Sin embargo, hay veces en que conviene hacerlo de forma diferente (para
adaptarse a una arquitectura cliente-servidor, porque haya clases sujetas a modificaciones frecuentes, etc.).
Además, aunque una clase se suele asociar a un solo componente, hay veces que conviene asociar una misma
clase a varios componentes.
Rose permite especificar el lenguaje en que se realizará cada componente. Esto permitiría, por
ejemplo, generar los componentes de la parte cliente en Visual Basic y los componentes de la parte servidor en
C++ en un sistema con arquitectura cliente-servidor.
DIAGRAMA DE DESPLIEGUE.
Los diagramas de despliegue muestran la configuración de elementos de proceso (el despliegue de
procesadores, periféricos, comunicaciones, etc.) y los componentes software (programas, procesos, etc. ) que
residen en ellos en tiempo de ejecución. En los diagramas de despliegue aparecen instancias de componentes,
pertenecientes al diagrama de componentes, mostrándose en qué nodos (procesadores) reside cada instancia.
En un diagrama de despliegue no pueden aparecer componentes que no existen como entidades en tiempo de
ejecución, como los ficheros fuente.
Los nodos de un diagrama de despliegue representan elementos físicos con capacida d de proceso o
facilitadores de algún servicio. Se puede especificar el tipo de un nodo o una instancia del mismo (en cuyo
caso se subrayará). Un nodo se representa tal como sigue:
Nombre
Rose utiliza dos representaciones diferentes para los nodos. Si el no do tiene capacidad de proceso
(como un ordenador, un servidor o similar), los laterales se ponen en negro:
Si el nodo no tiene capacidad de proceso (como un terminal, una impresora o un escaner), los laterales
no se rellenan:
Ingeniería del Software-UML 60
Los nodos son los elementos donde se encuentran o ejecutan las instancias de los componentes en
tiempo de ejecución. Para mostrar que una instancia de un componente reside o se ejecuta en un nodo, es decir,
que el nodo soporta una instancia de ese componente, se relaciona al nodo con la instancia mediante una
dependencia estereotipada como «support», tal y como se muestra a continuación:
OrdContabilidad : PC
«support
»
: ContaGes
.
OrdContabilidad: PC
: ContaGes
Los nodos están relacionados entre sí por asociaci ones, que indican caminos de comunicación. Una
asociación se representa gráficamente como una línea entre los nodos que comunica. Es común estereotipar las
asociaciones para indicar su tecnología.
Ingeniería del Software-UML 61
ServBD : Servidor
: SGBD
«LAN»
«RDSI» «RDSI»
DelegacionJaen : PC DelegacionToledo : PC
: CliGestor : CliGestor
Hay veces que una instancia de un componente puede migrar de un nodo a otro. Para modelar esta
migración se representa una relación entre dichas instancias con el estereotipo «become». Por ejemplo:
Nodo1
:A
: Cluster
«become»
Nodo2
: Cluster
Ingeniería del Software-UML 62
Aquí se representa la instancia : Cluster que en principio reside en Nodo1 y que en cierto momento
pasa a residir en Nodo2. Nótese que la instancia : A reside todo el tiempo en Nodo1.
Rose sólo permite un diagrama de despliegue. Por otro lado, Rose permite especificar, entre otras, el
tipo de planificación de tareas que se utiliza en cada nodo.
13
Para más información se recomienda consultar el documento “A Rational Development Process” de Philippe
Kruchten, disponible en http://www.rational.com/products/whitepapers/334.jsp.
Ingeniería del Software-UML 63
Las fases del ciclo de vida del Proceso Unificado de Desarrollo, desde el punto de vista organizativo,
son las siguientes:
- Concepción (inception): La “idea feliz”: especificación de la visión del producto final y los casos
de negocio.
- Elaboración (elaboration): Planificación de las actividades y recursos necesarios; especificación
de requisitos y diseño de la arquitectura.
- Construcción (construction): Construcción del producto y refinamiento hasta que el producto esté
preparado para su uso.
- Transición (transition): Realizar la transición de los clientes al producto generado, incluyendo
formación, soporte y mantenimiento hasta que los usuarios estén satisfechos.
Desde un punto de vista técnico, el ciclo de vida se divide en varias iteraciones (cuyo número y
duración depende de factores como la complejidad del software, experiencia del equipo y otros). Existe una
coincidencia en el tiempo de los hitos desde el punto de vista organizativo con los hitos desde el punto de vista
técnico, como es lógico:
Ingeniería del Software-UML 64
El énfasis en cada una de estas actividades depende de la fase e iteración en la que nos encontremos,
predominando al principio las actividades de análisis, más tarde las de diseño, luego las de construcción y por
último las de prueba y mantenimiento, como se puede ver en el siguiente gráfico:
El Proceso Unificado de Rational no está guiado por documentos, sino por el producto en sí. Los
documentos típicos a obtener pertenecen tanto al ámbito organizativo como técnico, incluyendo los modelos de
casos de uso, clases, interacción, etc., para lo cual se recomienda la utilización de herramientas CASE
apropiadas.
Ingeniería del Software-UML 65
GENERACIÓN DE CÓDIGO14.
En esta sección se dará una introducción básica sobre cómo generar y qué código se genera a partir
de los modelos realizados en Rose.
1. Comprobar el modelo.
Utilizando la opción Tools Check Model se comprueba que el modelo es consistente antes de generar
código. Aunque no es obligatorio, es muy recomendable realizarlo.
Se deben crear los componentes necesarios y sus relaciones (diagrama de componentes). Al crear un
componente se puede especificar su estereotipo (p. ej., programa principal, cabecera, cuerpo, etc.) y el
lenguaje en el que se generará (C++ en nuestro caso).
Dependiendo del lenguaje utilizado, una clase debe estar asignada a un solo componente, o varias
clases pueden estar asignadas a un mismo componente o, como en el caso de C++, una misma clase puede
pertenecer a dos componentes distintos (.h y .cpp). Esta asignación se hace arrastrando la clase desde el
browser y “soltándola” en el componente o desde la ficha realizes de la especificación del componente.
Estas propiedades controlarán el código que será generado. Rose proporciona unas propiedades por
defecto que pueden ser cambiadas según se requiera. Este cambio se puede hacer para todo el modelo desde
Tools Options (se recomienda hacer una copia con Clone y trabajar sobre ella) o para una clase en particular
14
Se recomienda consultar los apuntes de C++ dejados en el servidor donde se tratan conceptos como constructores
por copia, plantillas y la STL.
Ingeniería del Software-UML 66
abriendo su especificación. Entre las propiedades que se pueden establecer paralas clases están si Rose
generará operadores de igualdad (operador == y operador !=) o si generará el destructor y la visibilidad del
destructor en caso afirmativo. Cambiando el elemento seleccionado en el desplegable type de dicha opción se
puede acceder a otros elementos susceptibles de ser modificados para la generación de código, como por
ejemplo, las relaciones.
Se puede seleccionar una clase, un componente o un paquete para generar su código. También se
pueden seleccionar múltiples elementos mediante la tecla [Ctrl].
6. Generar el código.
Se puede generar código seleccionando Tools C++ Code Generation o desde el menú contextual.
Por defecto, el fichero o ficheros se generan en C:\Archivos de programa\Rational\Rose\C++\source siendo el
nombre de archivo el nombre del componente y la extensión .h o .cpp según el estereotipo del componente.
QUÉ SE GENERA .
Rose puede generar los siguientes elementos:
- Clases.
- Atributos (incluyendo visibilidad, tipo y valor por defecto).
- Declaraciones de operaciones (incluyendo parámetros, tipos de los parámetros y tipo devuelto).
- Relaciones (aunque sólo algunos tipos).
- Componentes (ficheros).
Coche
-cilindrada: double
+potencia(): double
El código generado para esta clase, dejando las opciones de generación de código por defecto, incluye:
- Definición de la clase, incluyendo la definición del atributo cilindrada y la operación potencia().
- Definición del constructor y constructor por copia y destructor. También genera el esqueleto del
código necesario para su implementación.
- Definición de las operaciones de comparación (igualdad y desigualdad) y la asignación. También
genera el esqueleto del código necesario para su implementación.
- Definición e implementación de las operaciones (privadas) set y get del atributo cilindrada.
Téngase en cuenta, sin embargo, que posiblemente la operación set se tendrá que retocar para
Ingeniería del Software-UML 67
evitar la introducción de valores inválidos en el atributo, como en este caso sería intentar asignar
un valor negativo a la cilindrada.
- Esqueleto para la implementación de la operación potencia().
Rose permite documentar la mayoría de los elementos. Al generar código, parte de esa documentación
aparecerá como comentario en el código. Por ejemplo, si documentamos la semántica de una operación de una
clase, esta documentación aparecerá como comentario encima de la definición de la operación al generar el
código.
El programador debería generar el código del cuerpo de dicho método entre las líneas //## begin
... y //## end ... . De esta forma, dicho código será preservado ( preserve=yes ) si se vuelve a generar
el código de esa clase.
No se deben borrar los códigos que genera Rose, ya que le son necesarios para si se desea volver a
generar código o se realiza ingeniería inversa.
Rose también proporciona espacios para introducir nuevo código, por ejemplo, para declaraciones
públicas:
class Coche
{
//## begin Coche%3A13C52B03A2.initialDeclarations preserve=yes
//## end Coche%3A13C52B03A2.initialDeclarations
public:
//## Constructors (generated)
Coche();
protected:
// Additional Protected Declarations
//## begin Coche%3A13C52B03A2.protected preserve=yes
//## end Coche%3A13C52B03A2.protected
private:
//## Get and Set Operations for Class Attributes (generated)
};
// Class Coche
// Class Coche
Coche::Coche()
//## begin Coche::Coche%3A13C52B03A2_const.hasinit preserve=no
//## end Coche::Coche%3A13C52B03A2_const.hasinit
//## begin Coche::Coche%3A13C52B03A2_const.initialization preserve=yes
//## end Coche::Coche%3A13C52B03A2_const.initialization
{
//## begin Coche::Coche%3A13C52B03A2_const.body preserve=yes
//## end Coche::Coche%3A13C52B03A2_const.body
}
Coche::~Coche()
{
//## begin Coche::~Coche%3A13C52B03A2_dest.body preserve=yes
//## end Coche::~Coche%3A13C52B03A2_dest.body
}
// Additional Declarations
//## begin Coche%3A13C52B03A2.declarations preserve=yes
//## end Coche%3A13C52B03A2.declarations
ClaseA ClaseB
1 1
ClaseA ClaseB
1 1
Si la asociación es uno a un número determinado, por defecto se utili zará una matriz de punteros. Por
ejemplo:
ClaseA ClaseB
1 4
Si la asociación es uno a muchos, se necesita algún tipo de contenedor para los punteros:
ClaseA ClaseB
1 0..*
Este es el código generado por defecto y no es compilable directamente por C++, a no ser que creemos
un contenedor con dicho nombre y semántica. Sin embargo, se podría utilizar, por ejemplo, alguno de los
contenedores proporcionados por la STL ( Standard Template Library) de C++, por ejemplo, la lista (list15).
Para ello, se debe cambiar en las opciones de compilación (seleccionando el tipo Project), la definición de
UnorderedUnboundedByReferenceContainer que está por defecto a
UnboundedSetByReference<$targetClass>> por list<*targetClass>. Además, hay que añadir la librería
list.h, utilizando por ejemplo la pestaña C++ de las especificaciones del componente (sección
AdditionalIncludes).
15
list es una clase parametrizada (plantilla).
Ingeniería del Software-UML 72
El código generado ahora, que puede ser compilado sin problemas, será:
Rose también tiene especificaciones propias para generar asociaciones en la que los elem entos deben
estar ordenados que podemos adaptar a nuestras librerías o a la STL para generar código compilable.
Una relación de agregación genera un código similar a una asociación. Por ejemplo:
ClaseA ClaseB
1 3
Sin embargo, en la relación de composición, la parte compuesta se tiene como un atributo de la clase
(esto es, por valor):
ClaseA ClaseB
1 3
En el caso de relaciones de dependencia, Rose sólo incluye en el código los “includes” que sean
necesarios.
Ingeniería del Software-UML 73
Rose también genera código para las relaciones de generalización. Por ejemplo:
Padre
Hija
class Padre {
...
} ;
Plantilla
EJEMPLO.
Como ejemplo de generación de código, veremos lo que se ge nera en la siguiente asociación:
ClaseA ClaseB
1 0..n
ClaseC
Ingeniería del Software-UML 74
class ClaseA {
...
private:
UnboundedSetByReference<ClaseC> the_ClaseC;
...
};
class ClaseB {
...
};
class ClaseC {
...
private
ClaseB *the_ClaseB;
...
};
Obsérvese que se podría utilizar co mo contenedor una lista para hacer que el código fuera compilable.