Tabla de Contenidos

02 - Diagrama de clases

El diagrama de clases es un diagrama UML que representa las clases de un sistema, sus atributos y métodos, y las relaciones entre ellas. Sirve para diseñar antes de codificar, comunicar el diseño y documentar el código existente.

1. La clase

Una clase se dibuja como un rectángulo con tres compartimentos: nombre, atributos y métodos.

La visibilidad se indica con un símbolo antes del nombre:

Símbolo Visibilidad En Java
+ Pública public
- Privada private
# Protegida protected
~ De paquete sin modificador

En PlantUML:

Book-id: long-title: String-stockQuantity: int+decrementStock(): void+isAvailable(): boolean

2. Relaciones

2.1 Dependencia

Una dependencia existe cuando una clase usa otra de forma puntual: recibe un objeto como parámetro, lo devuelve o lo crea. Es la relación más débil: no guarda referencias.

public class BookPrinter {
    public void print(Book book) { /* usa el objeto */ }
}

BookPrinterBookusa

La flecha discontinua (..>) significa *usa*. Si el diseño de Book cambia, BookPrinter puede verse afectado; leer las dependencias de un diagrama indica qué clases hay que revisar al cambiar otra.

2.2 Asociación

Una asociación es una relación estable: una clase guarda una referencia a otra. La multiplicidad indica cuántos objetos participan:

Notación Significado
1 Exactamente uno
0..1 Uno o ninguno
* o 0..* Cero o muchos
1..* Al menos uno


@startuml
!theme cerulean
skinparam backgroundColor transparent
skinparam shadowing false
skinparam ArrowThickness 1
skinparam classAttributeIconSize 0
skinparam class {
BackgroundColor #FEFEFE
BorderColor #344883
ArrowColor #344883
FontColor #343A40
}
skinparam classAttributeFontColor #343A40
skinparam stereotypeCBackgroundColor #344883
skinparam stereotypeCBorderColor #273768
skinparam package {
BackgroundColor transparent
BorderColor #344883
FontColor #343A40
}
skinparam package {
BackgroundColor transparent
BorderColor #344883
FontColor #343A40
}
skinparam ArrowColor #344883
skinparam participant {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
}
skinparam actor {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
}
skinparam sequence {
ArrowColor #344883
LifeLineBorderColor #94A3B8
GroupBorderColor #344883
GroupBackgroundColor #E9EDF7
}
skinparam note {
BackgroundColor #FEF9C3
BorderColor #B6C2DE
FontColor #343A40
}
skinparam activity {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
StartColor #344883
EndColor #344883
DiamondBackgroundColor #FEFEFE
DiamondBorderColor #344883
DiamondFontColor #343A40
}
skinparam component {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
}
skinparam database {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
}
skinparam node {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
}
skinparam cloud {
BackgroundColor transparent
BorderColor #344883
FontColor #344883
}
skinparam rectangle {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
}
skinparam state {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
}
skinparam usecase {
BackgroundColor #FEFEFE
BorderColor #344883
FontColor #343A40
}
class Order
class Book

Order "1" --> "*" Book : contains >
@enduml

public class Order {
    private final List<Book> books;
}

2.3 Agregación y composición

Ambas son asociaciones de *todo-parte*:

Relación Significado Ciclo de vida
Agregación La parte pertenece al todo, pero puede existir sin él Independiente
Composición La parte no tiene sentido sin el todo El todo gestiona la parte

TeamPlayerOrderOrderLineagregacióncomposición

Un jugador puede existir fuera del equipo (agregación, rombo hueco o–). Una línea de pedido no existe fuera del pedido (composición, rombo relleno *–).

2.4 Herencia y realización

La herencia (generalización) conecta una subclase con su superclase; la realización conecta una clase con la interfaz que implementa. Ambas se dibujan con flecha hueca: línea continua para herencia y discontinua para interfaces.

RepositoryBookRepositoryEntityBook

public class Book extends Entity implements Repository { /* ... */ }

3. Leer un diagrama

Pregunta Dónde mirar
¿Qué depende de esta clase? Flechas que apuntan hacia ella
¿De qué depende esta clase? Flechas que salen de ella
¿Qué se puede cambiar sin romper a otros? Clases con pocas flechas entrantes
¿Dónde está el núcleo del diseño? Clases a las que apuntan muchas dependencias

Las dependencias indican el impacto de un cambio: cuantas más clases dependen de una, más cuidado exige modificarla. Esta idea reaparece en las pruebas de arquitectura con ArchUnit, que comprueban automáticamente esas reglas en el código.

Antes de dibujar, pregúntate qué debe comunicar el diagrama: los conceptos del dominio y sus relaciones, no cada método interno.