# Bloque 3 · Tema 4
# Diseño y programación orientada a objetos. Elementos y componentes software: objetos, clases, herencia, métodos, sobrecarga. Ventajas e inconvenientes. Patrones de diseño y lenguaje de modelado unificado (UML).

---

# Esquema resumen

**POO — Pilares fundamentales**
- Abstracción
- Encapsulación
- Herencia
- Polimorfismo

**Elementos principales**

| Elemento | Descripción |
|---|---|
| Clase | Plantilla / molde |
| Objeto | Instancia de una clase |
| Atributo | Variable de una clase |
| Método | Función de una clase |
| Constructor | Inicializa el objeto al crearlo |
| Interfaz | Contrato sin implementación |
| Clase abstracta | No instanciable; puede tener métodos sin implementar |

**Relaciones entre clases**

| Relación | Tipo | Ejemplo |
|---|---|---|
| Herencia | Es-un | `Perro` es un `Animal` |
| Composición | Tiene-un (fuerte) | `Motor` forma parte de `Coche` |
| Agregación | Tiene-un (débil) | `Alumno` pertenece a `Clase` |
| Dependencia | Usa-un | `Pedido` usa `Producto` |

**Patrones de diseño (GoF)**

- Creacionales: Singleton, Factory Method, Abstract Factory, Builder, Prototype
- Estructurales: Adapter, Facade, Decorator, Composite, Proxy
- De comportamiento: Observer, Strategy, Template Method, Iterator, Command

**GRASP** — Patrones de asignación de responsabilidades:
Controller, Creator, Information Expert, Low Coupling, High Cohesion, Polymorphism, Indirection, Pure Fabrication, Protected Variations

**UML — Diagramas estructurales**
Clases, Objetos, Componentes, Paquetes, Despliegue, Compuesto

**UML — Diagramas de comportamiento**
Casos de uso, Actividades, Estados, Secuencia, Comunicación

---

# 1. Programación orientada a objetos

## 1.1 Concepto y origen

La **programación orientada a objetos (POO)** es un paradigma de programación que organiza el software en torno a **objetos**, que combinan datos (atributos) y comportamiento (métodos).

Surgió en los años 60 con **Simula 67** y se popularizó con **Smalltalk** en los 70. Hoy es el paradigma dominante, presente en Java, Python, C++, C#, Ruby, etc.

---

## 1.2 Pilares de la POO

### Abstracción

Consiste en representar solo las características esenciales de un objeto, ocultando los detalles internos no relevantes.

Ejemplo: al modelar un `Coche` para una app de parking, nos interesa la matrícula, la marca y el color; no el número de cilindros.

---

### Encapsulación

Agrupa los datos y los métodos que los manejan dentro de una misma clase, y restringe el acceso directo desde el exterior.

Se implementa mediante **modificadores de acceso**:

| Modificador | Acceso |
|---|---|
| `public` | Desde cualquier clase |
| `protected` | Desde la misma clase y sus subclases |
| `private` | Solo desde la propia clase |
| (sin modificador) | Solo desde el mismo paquete (Java) |

Los atributos suelen ser `private` y se exponen con métodos `getX()` / `setX()` (getters y setters).

---

### Herencia

Permite que una clase (**subclase** o clase hija) adquiera los atributos y métodos de otra clase (**superclase** o clase padre).

- Favorece la **reutilización de código**.
- Modela la relación **"es-un"**: un `Perro` es un `Animal`.
- En Java la herencia es **simple** (solo un padre directo). En C++ es **múltiple**.

**Sobreescritura (override)**: la subclase redefine un método heredado para adaptar su comportamiento.

```java
class Animal {
    public String sonido() { return "..."; }
}
class Perro extends Animal {
    @Override
    public String sonido() { return "Guau"; }
}
```

---

### Polimorfismo

Capacidad de un mismo método o referencia de comportarse de distinta forma según el tipo real del objeto.

Tipos:

| Tipo | Mecanismo | Cuándo se resuelve |
|---|---|---|
| **Polimorfismo de subtipos** | Herencia + sobreescritura | En tiempo de ejecución (dinámico) |
| **Sobrecarga (overloading)** | Mismo nombre, distintos parámetros | En tiempo de compilación (estático) |

**Sobrecarga**: varios métodos con el mismo nombre pero diferente firma (número o tipo de parámetros).

```java
class Calculadora {
    int sumar(int a, int b)         { return a + b; }
    double sumar(double a, double b){ return a + b; }
    int sumar(int a, int b, int c)  { return a + b + c; }
}
```

---

## 1.3 Elementos de una clase

| Elemento | Descripción |
|---|---|
| **Atributo (campo)** | Variable que almacena el estado del objeto |
| **Método** | Función que define el comportamiento |
| **Constructor** | Método especial que se ejecuta al crear el objeto (`new`) |
| **Destructor** | Libera recursos al destruirse el objeto (en Java: `finalize`; en C++: `~Clase()`) |
| **Método estático** | Pertenece a la clase, no a instancias concretas |
| **Atributo estático** | Valor compartido por todas las instancias |

---

## 1.4 Clases abstractas e interfaces

**Clase abstracta**:
- No puede instanciarse directamente.
- Puede tener métodos con y sin implementación (abstractos).
- Una subclase debe implementar todos los métodos abstractos.
- En Java: `abstract class Animal { abstract void sonido(); }`

**Interfaz**:
- Define un **contrato**: lista de métodos que una clase debe implementar.
- No tiene atributos de instancia (solo constantes).
- Una clase puede implementar **varias interfaces** (solución a la falta de herencia múltiple).
- En Java: `interface Volador { void volar(); }`

| | Clase abstracta | Interfaz |
|---|---|---|
| Instanciable | No | No |
| Herencia | Simple | Múltiple |
| Implementación de métodos | Puede tenerla | Solo desde Java 8 (`default`) |
| Atributos de instancia | Sí | No |

---

## 1.5 Relaciones entre clases

| Relación | Descripción | Símbolo UML |
|---|---|---|
| **Herencia** (generalización) | La subclase extiende la superclase | Flecha con triángulo hueco |
| **Realización** | Una clase implementa una interfaz | Flecha punteada con triángulo hueco |
| **Composición** | El objeto hijo no puede existir sin el padre | Rombo relleno |
| **Agregación** | El objeto hijo puede existir sin el padre | Rombo hueco |
| **Asociación** | Relación genérica entre clases | Línea |
| **Dependencia** | Una clase usa temporalmente otra | Flecha punteada |

---

## 1.6 Acoplamiento y cohesión

**Acoplamiento**: grado de dependencia entre clases.
- **Bajo acoplamiento** → deseable: cambios en una clase afectan poco a otras.

**Cohesión**: grado en que los elementos de una clase están relacionados entre sí.
- **Alta cohesión** → deseable: cada clase tiene una responsabilidad clara y bien definida.

> Regla de oro: **alta cohesión + bajo acoplamiento**.

---

## 1.7 Ventajas e inconvenientes de la POO

**Ventajas:**
- Reutilización de código (herencia, composición).
- Modularidad y mantenimiento más sencillo.
- Modelado más natural del mundo real.
- Facilita el trabajo en equipo.
- Encapsulación protege la integridad de los datos.

**Inconvenientes:**
- Mayor complejidad inicial frente a la programación estructurada.
- Peor rendimiento en sistemas de bajo nivel (overhead de objetos).
- Diseño incorrecto puede llevar a jerarquías de herencia rígidas.
- Curva de aprendizaje más pronunciada.

---

### Miniresumen

La POO se basa en **abstracción, encapsulación, herencia y polimorfismo**. Sus elementos clave son **clases, objetos, atributos y métodos**. Favorece la reutilización y el mantenimiento, a cambio de mayor complejidad inicial.

---

# 2. Patrones de diseño

## 2.1 Qué es un patrón de diseño

Un **patrón de diseño** es una solución reutilizable a un problema recurrente en el diseño de software. No es código concreto, sino una **plantilla conceptual** que describe cómo resolver una situación.

El catálogo más conocido es el del libro **"Design Patterns: Elements of Reusable Object-Oriented Software"** (1994), de los llamados **Gang of Four (GoF)**: Gamma, Helm, Johnson y Vlissides.

---

## 2.2 Clasificación GoF

Los 23 patrones GoF se dividen en tres categorías:

### Patrones creacionales
Gestionan el proceso de **creación de objetos**.

| Patrón | Descripción |
|---|---|
| **Singleton** | Garantiza que solo exista **una instancia** de una clase |
| **Factory Method** | Define una interfaz para crear objetos; las subclases deciden qué clase instanciar |
| **Abstract Factory** | Crea familias de objetos relacionados sin especificar sus clases concretas |
| **Builder** | Construye objetos complejos paso a paso |
| **Prototype** | Crea nuevos objetos **clonando** uno existente |

---

### Patrones estructurales
Definen cómo se **componen** clases y objetos.

| Patrón | Descripción |
|---|---|
| **Adapter** | Convierte la interfaz de una clase en otra que el cliente espera |
| **Facade** | Proporciona una interfaz simplificada a un subsistema complejo |
| **Decorator** | Añade responsabilidades a un objeto dinámicamente |
| **Composite** | Trata objetos individuales y composiciones de objetos de forma uniforme |
| **Proxy** | Proporciona un sustituto o representante de otro objeto |
| **Bridge** | Desacopla una abstracción de su implementación |
| **Flyweight** | Comparte objetos para soportar grandes cantidades de objetos de grano fino |

---

### Patrones de comportamiento
Gestionan la **comunicación** entre objetos.

| Patrón | Descripción |
|---|---|
| **Observer** | Un objeto notifica automáticamente a sus dependientes cuando cambia de estado |
| **Strategy** | Define una familia de algoritmos intercambiables en tiempo de ejecución |
| **Template Method** | Define el esqueleto de un algoritmo; las subclases rellenan los pasos |
| **Iterator** | Accede secuencialmente a los elementos de una colección sin exponer su estructura |
| **Command** | Encapsula una acción como objeto, permitiendo deshacer/rehacer |
| **Chain of Responsibility** | Pasa una petición a través de una cadena de objetos hasta que uno la procesa |
| **State** | El comportamiento de un objeto cambia según su estado interno |
| **Mediator** | Centraliza la comunicación entre objetos para reducir dependencias |

---

## 2.3 Patrón MVC

**Model-View-Controller** es un patrón arquitectónico que separa la aplicación en tres capas:

| Capa | Responsabilidad | Ejemplo |
|---|---|---|
| **Model** | Datos y lógica de negocio | Entidades, acceso a BD |
| **View** | Presentación al usuario | HTML, plantillas Thymeleaf |
| **Controller** | Recibe peticiones y coordina Model y View | Controladores REST/web |

Ventajas: separación de responsabilidades, facilita el testing, permite cambiar la vista sin tocar el modelo.

---

## 2.4 Patrones GRASP

**General Responsibility Assignment Software Patterns** — definen cómo asignar responsabilidades a clases y objetos.

| Patrón | Principio |
|---|---|
| **Information Expert** | Asigna la responsabilidad a la clase que tiene la información necesaria |
| **Creator** | Asigna la creación de objetos a la clase que los agrega, contiene o usa |
| **Controller** | Asigna el manejo de eventos del sistema a una clase controladora |
| **Low Coupling** | Minimiza las dependencias entre clases |
| **High Cohesion** | Cada clase tiene una responsabilidad bien definida |
| **Polymorphism** | Usa polimorfismo para manejar comportamientos alternativos |
| **Pure Fabrication** | Crea clases artificiales para mantener alta cohesión y bajo acoplamiento |
| **Indirection** | Introduce un intermediario para reducir el acoplamiento directo |
| **Protected Variations** | Protege los elementos de las variaciones en otros, usando interfaces estables |

---

## 2.5 Principios SOLID

Aunque no son patrones, suelen examinarse junto a ellos:

| Letra | Principio | Descripción |
|---|---|---|
| **S** | Single Responsibility | Una clase, una única responsabilidad |
| **O** | Open/Closed | Abierto a extensión, cerrado a modificación |
| **L** | Liskov Substitution | Las subclases deben poder sustituir a sus superclases |
| **I** | Interface Segregation | Mejor varias interfaces específicas que una general |
| **D** | Dependency Inversion | Depender de abstracciones, no de implementaciones concretas |

---

### Miniresumen

Los patrones GoF se dividen en **creacionales** (cómo crear), **estructurales** (cómo componer) y **de comportamiento** (cómo comunicar). Los más importantes en el examen son: **Singleton, Factory, Adapter, Facade, Observer y Strategy**. MVC es el patrón arquitectónico más usado en aplicaciones web.

---

# 3. UML — Lenguaje de Modelado Unificado

## 3.1 Qué es UML

**UML (Unified Modeling Language)** es un lenguaje estándar de modelado visual para describir, especificar, diseñar y documentar sistemas software.

- Desarrollado en los 90 por Booch, Rumbaugh y Jacobson en Rational Software.
- Estandarizado por el **OMG (Object Management Group)** en 1997.
- Versión actual: **UML 2.x**.
- No es un lenguaje de programación: es un **lenguaje de modelado**.

---

## 3.2 Clasificación de diagramas UML

UML 2 define **14 tipos de diagramas**, divididos en dos grandes grupos:

### Diagramas estructurales (qué ES el sistema)

| Diagrama | Descripción |
|---|---|
| **Clases** | Muestra clases, atributos, métodos y relaciones |
| **Objetos** | Instancias concretas de clases en un momento dado |
| **Componentes** | Módulos software (ejecutables, librerías, servicios web) y sus interfaces |
| **Paquetes** | Agrupación lógica de elementos del modelo |
| **Despliegue** | Infraestructura física: nodos, artefactos y conexiones |
| **Estructura compuesta** | Colaboración interna de una clase o componente |
| **Perfil** | Extensión del metamodelo UML para dominios específicos |

---

### Diagramas de comportamiento (qué HACE el sistema)

| Diagrama | Descripción |
|---|---|
| **Casos de uso** | Funcionalidades del sistema desde el punto de vista del usuario (actores) |
| **Actividades** | Flujo de trabajo o proceso; similar a un diagrama de flujo |
| **Máquina de estados** | Estados de un objeto y transiciones entre ellos |
| **Secuencia** | Interacción entre objetos ordenada en el tiempo (eje vertical) |
| **Comunicación** | Interacción entre objetos con énfasis en los enlaces (sin eje temporal) |
| **Tiempos** | Comportamiento en función del tiempo; usado en sistemas en tiempo real |
| **Resumen de interacción** | Combinación de diagramas de actividades y de interacción |

---

## 3.3 Diagrama de clases (el más importante)

### Representación de una clase

```
┌─────────────────────┐
│      Empleado       │  ← Nombre de la clase
├─────────────────────┤
│ - id: int           │  ← Atributos (visibilidad nombre: tipo)
│ - nombre: String    │
│ # salario: double   │
├─────────────────────┤
│ + getNombre(): String│ ← Métodos (visibilidad nombre(): tipo_retorno)
│ + calcularNomina()  │
└─────────────────────┘
```

Visibilidad: `+` público, `-` privado, `#` protegido, `~` paquete.

### Relaciones en el diagrama de clases

| Relación | Representación |
|---|---|
| Herencia (generalización) | Línea continua + triángulo hueco en el padre |
| Realización (interfaz) | Línea punteada + triángulo hueco |
| Asociación | Línea continua (con multiplicidad) |
| Composición | Línea + rombo **relleno** en el todo |
| Agregación | Línea + rombo **hueco** en el todo |
| Dependencia | Línea punteada + flecha abierta |

### Multiplicidad

| Notación | Significado |
|---|---|
| `1` | Exactamente uno |
| `0..1` | Cero o uno (opcional) |
| `*` o `0..*` | Cero o muchos |
| `1..*` | Uno o muchos |
| `2..5` | Entre dos y cinco |

---

## 3.4 Diagrama de casos de uso

Muestra **qué puede hacer** el sistema desde el punto de vista del usuario.

Elementos:
- **Actor**: entidad externa que interactúa con el sistema (persona, otro sistema). Se representa como un muñeco.
- **Caso de uso**: funcionalidad ofrecida. Se representa como una elipse.
- **Sistema**: rectángulo que enmarca los casos de uso.

Relaciones entre casos de uso:
- `«include»`: un caso de uso incluye obligatoriamente otro.
- `«extend»`: un caso de uso puede extender opcionalmente otro.
- Generalización: un actor o caso de uso hereda de otro.

---

## 3.5 Diagrama de secuencia

Muestra la **interacción entre objetos** ordenada temporalmente (de arriba a abajo).

Elementos:
- **Línea de vida** (lifeline): línea vertical punteada que representa un objeto.
- **Activación**: rectángulo sobre la línea de vida que indica cuándo está activo.
- **Mensaje**: flecha horizontal entre líneas de vida.
  - Síncrono: flecha rellena (espera respuesta).
  - Asíncrono: flecha abierta (no espera).
  - Respuesta: flecha punteada.

---

## 3.6 Diagrama de despliegue

Muestra la **arquitectura física** del sistema.

| Elemento | Descripción |
|---|---|
| **Nodo** | Recurso físico o virtual (servidor, dispositivo, VM) — cubo 3D |
| **Artefacto** | Elemento software desplegado (JAR, WAR, script, BD) |
| **Asociación** | Canal de comunicación entre nodos |

---

## 3.7 Diagrama de actividades

Similar a un diagrama de flujo; modela el **flujo de trabajo** de un proceso o algoritmo.

Elementos:
- Nodo inicial (círculo relleno).
- Actividad (rectángulo redondeado).
- Decisión / bifurcación (rombo).
- Barra de sincronización (barra gruesa horizontal) para concurrencia (fork/join).
- Nodo final (círculo relleno dentro de otro círculo).
- **Carriles (swimlanes)**: dividen las actividades por responsable o sistema.

---

### Miniresumen

UML define **14 tipos de diagramas** agrupados en estructurales (qué es) y de comportamiento (qué hace). Los más relevantes para el examen TAI son:

| Diagrama | Para qué se usa |
|---|---|
| **Clases** | Diseño lógico del sistema |
| **Casos de uso** | Requisitos desde el punto de vista del usuario |
| **Secuencia** | Interacción entre objetos en el tiempo |
| **Despliegue** | Arquitectura física e infraestructura |
| **Actividades** | Flujos de trabajo y procesos |

---

# Miniresumen final del tema

| Punto | Idea clave |
|---|---|
| **POO** | Paradigma basado en objetos; pilares: abstracción, encapsulación, herencia, polimorfismo |
| **Elementos** | Clase (molde), objeto (instancia), atributo (dato), método (comportamiento) |
| **Herencia/Sobrecarga** | Herencia: reutilización jerárquica. Sobrecarga: mismo nombre, distintos parámetros |
| **Ventajas POO** | Reutilización, modularidad, modelado natural. Inconveniente: mayor complejidad |
| **Patrones GoF** | Creacionales (Singleton, Factory), estructurales (Adapter, Facade), comportamiento (Observer, Strategy) |
| **GRASP** | Patrones de asignación de responsabilidades: Low Coupling, High Cohesion, Controller… |
| **MVC** | Patrón arquitectónico: Model (datos), View (presentación), Controller (coordinación) |
| **SOLID** | 5 principios de diseño: S, O, L, I, D |
| **UML** | 14 diagramas; más importantes: Clases, Casos de uso, Secuencia, Despliegue, Actividades |
