En UML, la relación <<extend>> se utiliza para indicar que un caso de uso agrega comportamiento a otro caso de uso bajo ciertas condiciones. A diferencia de <<include>>, la extensión no representa comportamiento obligatorio.
La extensión sirve para modelar comportamiento opcional, condicional o excepcional que se incorpora en un punto determinado del caso de uso base. Si la condición no ocurre, el caso base puede completarse sin ejecutar el caso extensor.
Usar bien <<extend>> ayuda a separar variantes importantes sin sobrecargar el caso de uso principal. Usarlo mal puede hacer que el diagrama sea difícil de leer y que parezca más técnico de lo necesario.
Extender significa agregar comportamiento a un caso de uso base en una situación particular. El caso base tiene sentido por sí mismo y puede ejecutarse sin la extensión. El caso extensor aparece solo si se cumple una condición.
Por ejemplo, en un sistema de turnos, el caso de uso Solicitar turno puede completarse normalmente. Pero si el paciente desea recibir un recordatorio, puede ejecutarse un comportamiento adicional llamado Programar recordatorio.
La relación <<extend>> se representa con una línea discontinua y una flecha abierta que apunta desde el caso de uso extensor hacia el caso de uso base. Sobre la línea se coloca el texto <<extend>>.
La dirección de la flecha es importante: apunta al caso que está siendo extendido. Si Programar recordatorio extiende Solicitar turno, la flecha va desde Programar recordatorio hacia Solicitar turno.
En el ejemplo, Solicitar turno es el caso base. Puede terminar con la reserva confirmada sin necesidad de programar un recordatorio. Programar recordatorio solo se ejecuta si el paciente elige recibir un aviso antes de la consulta. Por eso se modela como una extensión condicional.
En una relación de extensión hay dos partes:
El caso extensor no reemplaza al caso base. Solo agrega una variante, una opción o un comportamiento adicional.
Conviene usar extensión cuando se cumplen estas condiciones:
Si la variante es pequeña o simple, puede ser suficiente describirla como flujo alternativo en la especificación textual.
No toda alternativa necesita una relación <<extend>>. Muchas variantes se documentan mejor como flujos alternativos dentro del caso de uso.
Por ejemplo, si al solicitar un turno no hay horarios disponibles, puede documentarse como flujo alternativo. No siempre es necesario crear un caso de uso extensor llamado Informar falta de disponibilidad.
La extensión conviene cuando la variante tiene suficiente entidad, puede reutilizarse o conviene mostrarla explícitamente en el diagrama.
En un sistema de turnos médicos, podrían aparecer extensiones como estas:
| Caso base | Caso extensor | Condición |
|---|---|---|
| Solicitar turno | Programar recordatorio | El paciente acepta recibir un aviso antes de la consulta. |
| Solicitar turno | Validar cobertura especial | El turno corresponde a una prestación que requiere autorización. |
| Cancelar turno | Registrar motivo de cancelación | La clínica exige motivo para cancelaciones tardías. |
| Consultar agenda diaria | Exportar agenda | El médico solicita descargar la agenda. |
UML permite definir puntos de extensión, que indican en qué parte del caso base puede insertarse el comportamiento extensor. En la práctica, muchas veces basta con aclararlo en la especificación textual.
Por ejemplo, en Solicitar turno, Programar recordatorio podría ejecutarse después de confirmar la reserva y antes de mostrar el comprobante final. Ese punto debe quedar claro para evitar ambigüedad.
Si un comportamiento ocurre siempre, no corresponde modelarlo con <<extend>>. En ese caso puede formar parte del flujo principal o, si se reutiliza y conviene separarlo, podría analizarse como <<include>>.
Por ejemplo, si el sistema siempre debe validar disponibilidad antes de reservar un turno, no es una extensión. Es parte obligatoria del proceso.
Otro error frecuente es usar extensiones para representar todas las opciones de un menú. Un diagrama de casos de uso no debe convertirse en un mapa de navegación de la interfaz.
Si el usuario puede elegir entre varias funcionalidades independientes, cada una puede ser un caso de uso asociado al actor. No necesariamente deben extenderse entre sí.
La diferencia central es la obligatoriedad. <<include>> indica comportamiento que siempre se incorpora al caso base. <<extend>> indica comportamiento adicional que se ejecuta solo si se cumple una condición.
| Relación | Cuándo ocurre | Dirección de la flecha |
|---|---|---|
| <<include>> | Siempre que se ejecuta el caso base. | Desde el caso base hacia el caso incluido. |
| <<extend>> | Solo si se cumple una condición. | Desde el caso extensor hacia el caso base. |
La especificación textual debe indicar la condición que activa la extensión y el punto donde ocurre. Si solo se dibuja la flecha en el diagrama, el lector puede no entender cuándo se ejecuta el comportamiento extensor.
Ejemplo:
Antes de usar extensión, conviene preguntar:
Al usar <<extend>>, suelen aparecer estos errores:
La relación <<extend>> permite representar comportamiento que se agrega a un caso de uso bajo determinadas condiciones. Es útil cuando la variante tiene suficiente importancia para mostrarse explícitamente y cuando el caso base sigue teniendo sentido sin ella.
La regla práctica es usar extensión con moderación: si la condición es clara y la variante aporta comprensión al modelo, puede ser adecuada. Si solo se trata de un detalle menor, suele ser mejor documentarlo como flujo alternativo. En el próximo tema estudiaremos la generalización de actores y de casos de uso.