====== 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. ┌──────────────────────────────┐ │ Book │ ├──────────────────────────────┤ │ - id: long │ │ - title: String │ │ - stockQuantity: int │ ├──────────────────────────────┤ │ + decrementStock(): void │ │ + isAvailable(): boolean │ └──────────────────────────────┘ 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: @startuml class Book { - id: long - title: String - stockQuantity: int + decrementStock(): void + isAvailable(): boolean } @enduml ===== 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 */ } } @startuml BookPrinter ..> Book : usa @enduml 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 class Order class Book Order "1" --> "*" Book : contains > @enduml public class Order { private final List 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 | @startuml class Team class Player class Order class OrderLine Team o-- Player : agregación Order *-- OrderLine : composición @enduml 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. @startuml interface Repository class BookRepository class Entity class Book Entity <|-- Book Repository <|.. BookRepository @enduml 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.