Definición. UML (Unified Modeling Language) es un lenguaje gráfico para visualizar, especificar, construir y documentar los artefactos de un sistema con gran cantidad de software. Cubre tanto aspectos conceptuales (procesos de negocio, funciones del sistema) como cosas concretas (clases, esquemas de bases de datos, componentes reutilizables). Breve historia Los lenguajes de modelamiento orientados a objetos aparecieron entre mediados de los 70's y fines de los 80's, debido a dos factores fundamentales: la aparición de lenguajes orientados a objetos, y la aparición de aplicaciones cada vez más complejas. En 1989 habían aproximadamente 10 métodos orientados a objetos. En 1994 más de 50. Esta época fue llamada la "guerra de los métodos". Entre todos estos métodos destacaron tres: el de Booch, el OOSE (Object-Oriented Software Engineering) de Jacobson, y el OMT (Object Modeling Technique) de Rumbaugh. Otros métodos importantes fueron: Fusion, Shlaer-Mellor y Coad-Yourdon. A mediados de los 90's cada autor de los tres métodos más reconocidos (Booch, Jacobson y Rumbaugh) empieza a adoptar ideas de los otros 2 métodos. En 1994 Rumbaugh se une a Booch, y sacan la versión 0.8 de Unified Method, el cual es publicado en 1995. Luego Jacobson se une a Rational, y sacan la versión 0.9 de UML, en junio de 1996. Posteriormente sacan la versión 1.0 en enero de 1997, con la aprobación de un grupo de empresas llamado OMG (Object Management Group). El lenguaje es abierto a otras empresas, y con nuevas observaciones y recomendaciones sale la versión 1.1 en noviembre de 1997, y la versión 1.2 en junio de 1998. A fines de 1998 sale la actual versión 1.3. Casos de Uso Ningún sistema se encuentra aislado. Cualquier sistema interactúa con actores humanos o mecánicos que lo utilizan con algún objetivo. Un caso de uso especifica el comportamiento de un sistema o una parte del mismo, y es una descripción de un conjunto de secuencias de acciones, donde cada secuencia representa la interacción de los elementos externos del sistema (sus actores) con el propio sistema. Un caso de uso representa un requerimiento funcional del sistema. Por ejemplo, un caso de uso fundamental en un banco, es el procesamiento de préstamos. Gráficamente, los casos de uso se representan mediante elipses. Los casos de uso se emplean para capturar el comportamiento deseado del sistema en desarrollo, sin tener que especificar cómo se implementa ese comportamiento. Proporcionan un medio para que los desarrolladores, los usuarios finales del sistema y los expertos del dominio lleguen a una comprensión común del sistema. Además ayudan a validar la arquitectura y a verificar el sistema mientras evoluciona a lo largo del desarrollo. Ejemplo: Un juego de dados Se tiene un juego de dados en que un jugador lanza dos dados. Si el total obtenido es siete, el jugador gana, de lo contrario pierde. Caso de uso: Juega un juego. Participantes (actores): Jugador. Descripción: Este caso de uso comienza cuando el jugador recoge y tira los dados. Si los puntos suman siete, gana y pierde si suman cualquier otro número. El diagrama UML correspondiente a este caso de uso sería similar a este: Cada caso de uso debe tener un nombre que lo distinga de otros casos de uso. Los nombres pueden ser nombres simples o nombres de camino. Estos últimos constan del nombre del caso de uso, precedido del nombre del paquete en el que se encuentra. Ejemplo: Un actor representa un conjunto coherente de roles que juegan los usuarios de los casos de uso cuando interactúan con éstos. Los actores pueden ser personas o sistemas mecánicos. Se pueden definir categorías generales de actores (como cliente en el ejemplo de abajo) y especializarlos (como ClienteComercial) a través de relaciones de generalización. Ejemplo: Los casos de uso pueden ser versiones especializadas de otros casos de uso, casos de uso incluidos como parte de otros casos de uso, y casos de uso que extienden el comportamiento de otros casos de uso básicos. Organización de casos de uso Los casos de uso pueden organizarse agrupándolos en paquetes. También se pueden especificar relaciones de generalización, inclusión y extensión. Generalización significa que el caso de uso hijo hereda el comportamiento y el significado del caso de uso padre, donde el hijo puede agregar o redefinir el comportamiento del padre. La generalización entre casos de uso se representa como una línea continua con una punta de flecha vacía. Una relación de inclusión entre dos casos de uso significa que un caso de uso base incorpora explícitamente el comportamiento de otro caso de uso en el lugar especificado en el caso base. Aquí el caso de uso base toma el comportamiento del caso de uso proveedor. Esta relación se usa para evitar describir el mismo flujo de eventos repetidas veces, poniendo el comportamiento común en un caso de uso aparte (que será incluido por un caso base). Una relación de inclusión se representa como una dependencia, usando la palabra include. Para especificar la posición en un flujo de eventos, se usa la palabra include seguido del caso de uso que se quiere incluir. Por ejemplo, para describir el flujo de Seguir pedido: Flujo de eventos principal: Obtener y verificar el número de pedido. include (validar usuario). Examinar el estado de cada parte del pedido y preparar un informe para el usuario. Una relación de extensión entre casos de uso significa que un caso de uso base incorpora implícitamente el comportamiento de otro caso de uso en el lugar especificado indirectamente por el caso de uso que extiende al base. Un caso de uso puede extenderse solamente en ciertos puntos, llamados puntos de extensión. La extensión se puede ver como que el caso de uso que extiende, incorpora su comportamiento en el caso de uso base. Se representa como una dependencia con la palabra extend. Los puntos de extensión sólo son etiquetas que pueden aparecer en el flujo del caso de uso base. Por ejemplo, el flujo de Hacer pedido podría escribirse así: Flujo de eventos principal: include (Validar usuario). Recoger los ítemes del pedido del usuario. (establecer prioridad). Enviar el pedido para ser procesado. Una relación de extensión se usa para modelar la parte de un caso de uso que el usuario puede ver como comportamiento opcional del sistema. De esta forma se separa el comportamiento opcional del obligatorio. Es decir, un caso de uso base puede, bajo ciertas condiciones, incorporar el comportamiento de otro caso de uso en el lugar especificado. Modelando el comportamiento de un elemento Por lo general, los casos de uso se utilizan para modelar el comportamiento de un elemento, ya sea un sistema completo, un subsistema o una clase. Es importante centrarse en lo que hace el elemento, no en cómo lo hace. Los casos de uso sirven de base para probar cada elemento según evoluciona durante el desarrollo. Al probar continuamente cada elemento frente a sus casos de uso, se está validando su implementación a lo largo del desarrollo. Para modelar el comportamiento de un elemento se debe: - Identificar los actores que interactúan con el elemento. - Organizar los actores similares en jerarquías, identificando los roles. - Considerar las formas más importantes que tiene cada actor de interactuar con el elemento. También hay que considerar las formas excepcionales (puntos de extensión). - Organizar estos comportamientos como casos de uso, usando las reglas de inclusión (para factorizar el comportamiento común) y de extensión (para distinguir el comportamiento excepcional). Ejemplo 1: Sistema de ventas. Un sistema de ventas debe interactuar con clientes, los cuales efectúan pedidos. Además los clientes pueden hacer un seguimiento de sus propios pedidos. El sistema envía los pedidos y las facturas a los clientes. En algunos casos, según la urgencia de los clientes, se puede adelantar parte del pedido (pedidos parciales). Como se muestra en la figura anterior, el comportamiento de este sistema se puede modelar usando los casos de uso Hacer pedido, Seguir pedido, Enviar pedido, Facturar cliente. El comportamiento común puede factorizarse (Validar cliente) y también pueden distinguirse sus variantes (Enviar pedido parcial). Cada caso de uso debe incluir una especificación de su comportamiento. Ejemplo 2:Validación de tarjetas de crédito. La figura de abajo muestra el contexto de un sistema de validación de tarjetas de crédito. Se puede ver que existen dos categorías de clientes: clientes individuales, clientes corporativos. Estos actores representan los roles que juegan las personas que interactúan con el sistema. También hay actores que representan otras instituciones, como Comercio, con el cual el cliente realiza una transacción para comprar un artículo o servicio, y Entidad financiera, que por lo general es una entidad bancaria donde el usuario tiene la tarjeta de crédito. Modelado del contexto de un sistema Modelando los requerimientos de un sistema Un requisito es una característica de diseño, una propiedad o un comportamiento de un sistema. Cuando se enuncian los requisitos de un sistema, se está estableciendo un contrato entre los elementos externos al sistema y el propio sistema, que establece lo que se espera que el sistema haga. De aquí la importancia de que antes de construir un sistema, exista un acuerdo sobre qué debería hacer el sistema. Sin embargo, es casi seguro que la comprensión de los requisitos va a evolucionar conforme se vaya implementanto el sistema de manera iterativa e incremental. La mayoría de los requerimientos funcionales de un sistema, si no todos, se pueden expresar con diagramas de casos de uso. Para expresar los requerimientos funcionales también puede usarse desde texto sin estructura, hasta expresiones en un lenguaje formal. La principal diferencia al modelar requerimientos funcionales, es que se introducen en los diagramas, casos de uso adicionales que pueden ser invisibles para los actores, pero que son comportamientos fundamentales del sistema. La siguiente figura extiende el diagrama de casos de uso anterior. Modelado de los requisitos de un sistema