Archyno
UMLDiagramas de estructura

Diagramas de clases UML

El diagrama de estructura que carga con la mayor parte del vocabulario de UML: los tipos, sus atributos y operaciones, y las seis clases de línea que los conectan. Aprende bien este y los otros seis diagramas de estructura casi no cuestan nada.

11 min de lecturaUML 2.5.14 de 35

La respuesta corta

  • Agregación y composición significan ambas tiene-un. La única diferencia es si las partes sobreviven al todo: rombo hueco sí, rombo relleno no.
  • La generalización es línea continua con triángulo hueco, la realización discontinua con el mismo triángulo. Continua dice es-un-tipo-de, discontinua cumple-el-contrato-de.
  • La multiplicidad va en el extremo de la asociación, no en el medio: 1, 0..1, 1..*, y un asterisco suelto como abreviatura de 0..*.
  • Un diagrama de clases modela tipos con comportamiento; uno ER, los datos almacenados. Un dominio suele tener ambos, sin coincidir elemento a elemento.
Diagrama de clases UML de un dominio de pagos. Merchant está asociado con Payment, de uno a muchos. Payment se compone de un Money y cero o más Refund, y está asociado con una interfaz PaymentMethod que realizan tanto Card como BankTransfer.
Un diagrama de clases de un dominio de pagos. Cada marca que aparece en él se explica más abajo, y el mismo dominio reaparece en todos los demás artículos de esta serie.

01Leer la caja#

Una clase es un rectángulo con hasta tres compartimentos apilados. Solo el primero es obligatorio.

  • Nombre. El nombre del tipo, centrado y en negrita. Si la clase es abstracta, el nombre va en cursiva. Una palabra clave entre comillas angulares encima - «interface», «enumeration» - acota de qué tipo de clasificador se trata.
  • Atributos. Uno por línea, escritos como visibilidad nombre: Tipo [multiplicidad] = valor por defecto. Todo salvo el nombre es opcional.
  • Operaciones. Una por línea, escritas como visibilidad nombre(parámetros): TipoDeRetorno.

El símbolo inicial de cada miembro es su visibilidad: + público, - privado, # protegido y ~ de paquete. Un miembro subrayado es estático: pertenece a la clase y no a una instancia.

02Las seis líneas#

Casi todo el significado de un diagrama de clases está en las líneas, y solo seis merecen memorizarse. El extremo que lleva el adorno es significativo en todos los casos.

ElementoNotaciónQué significa
AsociaciónUn enlace estructural. Las instancias de una conocen a las de la otra. La multiplicidad en cada extremo dice cuántas.
Asociación dirigidaLo mismo, pero navegable solo en el sentido de la flecha. Payment puede alcanzar su PaymentMethod; el método no puede volver.
AgregaciónUn enlace todo-parte donde la parte sobrevive al todo. El rombo hueco se coloca en el todo.
ComposiciónUn enlace todo-parte donde la parte muere con el todo. Rombo relleno en el todo. Una parte tiene exactamente un dueño.
GeneralizaciónHerencia. El triángulo hueco apunta al padre. Léelo como «es un tipo de».
RealizaciónImplementación de una interfaz. Línea discontinua, triángulo hueco en la interfaz.
DependenciaEl enlace más débil: una usa a la otra, normalmente como parámetro o variable local. Úsala con moderación o acabarás con cada clase conectada a todas las demás.

Las líneas continuas sin triángulo son estructurales; las discontinuas son siempre más débiles que las continuas.

03Multiplicidad#

El número al final de una línea dice cuántas instancias participan. Se coloca en el extremo opuesto a la clase que restringe, y eso despista: al leer Merchant 1 —— 0..* Payment, el 0..* junto a Payment significa que un comercio tiene cero o más pagos.

  • 1 - exactamente una. El valor por defecto cuando no se escribe nada, aunque escribirlo es más claro.
  • 0..1 - opcional. Esta es la notación de una referencia que puede estar vacía.
  • * o 0..* - cualquier número, incluido ninguno.
  • 1..* - al menos una. Una restricción con sentido y que se olvida a menudo.
  • 2..4 - un rango explícito.

La multiplicidad es la victoria en corrección más barata de toda la notación. «¿Esto puede estar vacío?» y «¿puede haber más de uno?» son las dos preguntas que sacan a la luz los desacuerdos reales en una revisión de diseño, y la respuesta se anota con tres caracteres.

04Asociación, agregación, composición#

Estas tres son la misma forma de relación con tres intensidades, y la diferencia va del ciclo de vida, no de lo relacionadas que parezcan las dos cosas.

Dos diagramas contrastados. A la izquierda, Payment tiene un rombo relleno hacia Money, etiquetado composición: el Money no puede existir sin el Payment. A la derecha, Team tiene un rombo hueco hacia Person, etiquetado agregación: una Person sobrevive al equipo.
La prueba es el borrado. Composición a la izquierda: destruye el todo y la parte se destruye con él. Agregación a la derecha: la parte continúa.

Una asociación simple no afirma nada sobre propiedad. Dos cosas están enlazadas. Eso es todo, y es el valor por defecto correcto.

La agregación - el rombo hueco - afirma una relación todo-parte en la que la parte es independiente. Consejo honesto: la agregación no lleva casi ninguna semántica formal en UML 2.5.1, y los lectores no se ponen de acuerdo sobre qué implica. Si dudas entre asociación y agregación, dibuja la asociación.

La composición - el rombo relleno - es la que dice algo fuerte y comprobable. La parte pertenece a exactamente un todo y se destruye con él. En el modelo de pagos, un Refund existe solo como parte de un Payment; no hay reembolsos flotando sueltos. Esa es una restricción real, que merece registrarse, y se traduce directamente en un borrado en cascada o una colección poseída en el código.

05Cuándo dibujar uno#

Úsalo cuando

  • Acordar el vocabulario del dominio con gente que no va a leer el código
  • Las relaciones tienen restricciones reales: opcionalidad, cardinalidad, propiedad
  • Formar a alguien en un subsistema cuya forma no se ve en el árbol de archivos
  • Diseñar un esquema, un contrato de API o cualquier cosa con estructura persistida

Usa otra cosa cuando

  • Estarías redibujando lo que un IDE genera del código fuente con un clic
  • La pregunta va de orden o de tiempo: dibuja un diagrama de secuencia o de actividad
  • Las clases son pura fontanería del framework sin significado de dominio
  • Te tienta meter todas las clases del sistema en un mismo lienzo

En la práctica, los diagramas de clases más útiles son pequeños. De siete a doce clases, atributos solo en aquellas de las que se está hablando y omitidos en el resto, y cada línea con su multiplicidad. Un diagrama así se lee en una reunión y zanja discusiones. Un diagrama de clases de cien cajas es un artefacto, no una comunicación.

06Cinco errores que conviene evitar#

  1. Flechas apuntando al revés. La generalización y la realización apuntan a la abstracción. Si tu triángulo está en la subclase, el diagrama dice lo contrario de lo que querías.
  2. Composición usada para «muy relacionado». El rombo relleno es una afirmación sobre el ciclo de vida. Úsalo solo cuando destruir el todo destruya de verdad la parte.
  3. Sin multiplicidades. Una línea sin nada en los extremos ha tirado la información más valiosa que el diagrama podía llevar.
  4. Mezclar alturas. Clases de dominio y clases del framework en un mismo lienzo. Divídelo; cada diagrama debe ser legible para un solo público.
  5. Modelar cada getter. Las operaciones van en el diagrama cuando llevan significado. getName() no lo lleva.

Si quieres contrastar un modelo de clases con la realidad, dibuja un diagrama de objetos: una única instantánea concreta de instancias. Las multiplicidades que parecían correctas en abstracto suelen caerse en cuanto intentas rellenarlas con valores reales.

En una línea cada uno

  1. 01Tres compartimentos: nombre, atributos, operaciones. Mejor omitir que dejar vacío.
  2. 02Los marcadores de visibilidad son + - # ~; el subrayado significa estático y el nombre en cursiva, abstracto.
  3. 03Seis líneas llevan el significado; el extremo adornado siempre es significativo.
  4. 04La generalización y la realización apuntan a la abstracción.
  5. 05La composición afirma un ciclo de vida: la parte muere con el todo. La agregación apenas significa nada; prefiere una asociación simple.
  6. 06La multiplicidad es la victoria en corrección más barata disponible. Ponla en cada línea.

07Preguntas frecuentes#

¿Qué diferencia hay entre agregación y composición?

Ambas significan tiene-un, y la diferencia está en qué ocurre cuando se destruye el todo. La agregación, rombo hueco, significa que las partes sobreviven al todo: borra un departamento y sus empleados siguen existiendo. La composición, rombo relleno, significa que no: borra un pedido y sus líneas se van con él.

¿Qué significan los signos más, menos y almohadilla en un diagrama de clases?

Son marcas de visibilidad sobre atributos y operaciones, escritas justo antes del nombre del miembro. Más es público, menos privado, la almohadilla protegido y la virgulilla visible en el paquete.

¿Qué significa 0..* en UML?

Es una multiplicidad y quiere decir cero o más. La multiplicidad va en el extremo de una asociación y limita cuántas instancias de ese extremo pueden participar: 1 es exactamente una, 0..1 es opcional, 1..* es una o más, y un asterisco suelto abrevia 0..*.

¿Qué diferencia hay entre generalización y realización?

La generalización es herencia entre dos clases, dibujada con línea continua y triángulo hueco. La realización es una clase que implementa una interfaz, dibujada con línea discontinua y el mismo triángulo hueco. Continua dice es-un-tipo-de; discontinua dice cumple-el-contrato-de.

¿En qué se diferencia un diagrama de clases UML de uno ER?

Un diagrama de clases modela tipos con comportamiento, por eso las operaciones van en la clase, y describe objetos en memoria. Un diagrama ER modela los datos que el sistema almacena, no tiene operaciones, y sus relaciones se limitan a lo que una base relacional puede imponer. Un mismo dominio suele tener ambos, y no tienen por qué coincidir elemento a elemento.

En esta serie

Lecturas relacionadas

Todos los artículos