B3-T4: PATRONES DE DISEÑO (GoF), PRINCIPIOS SOLID Y ARQUITECTURA DE SOFTWARE
Tema clave y muy preguntado. Los patrones GoF más frecuentes en el examen son: Singleton, Factory Method, Abstract Factory, Observer, Strategy, Adapter, Decorator, Facade y MVC. SOLID es casi fijo. Memoriza qué tipo es cada patrón (creacional/estructural/comportamiento) y una descripción breve de cada uno — es lo que más preguntan.
PRINCIPIOS SOLID
Acuñados por Robert C. Martin ("Uncle Bob"). Son cinco principios de diseño orientado a objetos para crear software mantenible, extensible y robusto.
| Letra | Principio | Enunciado | Consecuencia de violarlo |
|---|---|---|---|
| S | Single Responsibility (Responsabilidad única) | Una clase debe tener una sola razón para cambiar (una sola responsabilidad) | Clases "dios" que hacen demasiado, difíciles de mantener |
| O | Open/Closed (Abierto/Cerrado) | Las entidades de software deben estar abiertas a la extensión pero cerradas a la modificación | Cada nuevo requisito obliga a modificar código existente (riesgo de regresión) |
| L | Liskov Substitution (Sustitución de Liskov) | Los objetos de una subclase deben poder sustituir a los de la clase base sin alterar el comportamiento correcto | Subclases que rompen el contrato de la clase base (ej: cuadrado que hereda de rectángulo) |
| I | Interface Segregation (Segregación de interfaces) | Los clientes no deben depender de interfaces que no usan. Mejor muchas interfaces específicas que una general | Interfaces "gordas" que obligan a implementar métodos innecesarios |
| D | Dependency Inversion (Inversión de dependencias) | Los módulos de alto nivel no deben depender de los de bajo nivel. Ambos deben depender de abstracciones | Acoplamiento fuerte entre capas, difícil de testear y cambiar |
Examen: El principio de Liskov es de Barbara Liskov (1987). El principio Open/Closed fue enunciado originalmente por Bertrand Meyer (1988). La inversión de dependencias se implementa con inyección de dependencias (DI) y contenedores IoC.
OTROS PRINCIPIOS DE DISEÑO
| Principio | Descripción |
|---|---|
| DRY (Don't Repeat Yourself) | Cada pieza de conocimiento debe tener una representación única y no ambigua en el sistema |
| KISS (Keep It Simple, Stupid) | Mantener el diseño lo más simple posible |
| YAGNI (You Aren't Gonna Need It) | No implementar funcionalidad hasta que sea necesaria (principio de XP) |
| Alta cohesión | Los elementos de un módulo deben estar estrechamente relacionados entre sí |
| Bajo acoplamiento | Los módulos deben tener la mínima dependencia posible entre sí |
| Composición sobre herencia | Preferir componer objetos que heredar de clases base (GoF lo recomienda explícitamente) |
| Ley de Demeter | Un objeto solo debe hablar con sus colaboradores inmediatos (no con los amigos de los amigos) |
| Separación de concerns | Cada módulo/capa debe abordar un aspecto distinto del problema |
PATRONES DE DISEÑO GoF
Los 23 patrones de diseño fueron catalogados por Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides en su libro "Design Patterns: Elements of Reusable Object-Oriented Software" (1994), conocidos como la Gang of Four (GoF).
Clasificación
| Categoría | Propósito | Patrones (5 + 7 + 11 = 23) |
|---|---|---|
| Creacionales (5) | Cómo se crean los objetos | Abstract Factory, Builder, Factory Method, Prototype, Singleton |
| Estructurales (7) | Cómo se componen clases y objetos | Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy |
| De comportamiento (11) | Cómo interactúan y se reparten responsabilidades | Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor |
PATRONES CREACIONALES
| Patrón | Intención | Cuándo usarlo | Ejemplo real |
|---|---|---|---|
| Singleton | Garantizar que una clase tenga exactamente una instancia y proporcionar un punto de acceso global | Conexión a BBDD, logger, configuración global, pool de recursos | Runtime.getRuntime() en Java |
| Factory Method | Definir una interfaz para crear objetos, dejando que las subclases decidan qué clase instanciar | Frameworks que crean objetos sin conocer la clase concreta | Collection.iterator() |
| Abstract Factory | Proporcionar una interfaz para crear familias de objetos relacionados sin especificar clases concretas | Kits de UI multiplataforma (botones, ventanas para Windows/Mac/Linux) | GUI toolkits, drivers de BBDD |
| Builder | Separar la construcción de un objeto complejo de su representación | Objetos con muchos parámetros opcionales, construcción paso a paso | StringBuilder, fluent APIs |
| Prototype | Crear objetos nuevos clonando un prototipo existente | Cuando crear un objeto desde cero es costoso pero copiarlo es eficiente | Object.clone() en Java |
Examen: Singleton es el más preguntado. Cuidado: Singleton dificulta los tests unitarios (estado global). Factory Method usa herencia (subclases deciden). Abstract Factory usa composición (familias de productos). La diferencia es sutil pero cae.
PATRONES ESTRUCTURALES
| Patrón | Intención | Cuándo usarlo | Ejemplo real |
|---|---|---|---|
| Adapter | Convertir la interfaz de una clase en otra que el cliente espera. Permite que clases incompatibles trabajen juntas | Integrar código legacy o librerías de terceros con interfaz diferente | Arrays.asList(), adaptadores de enchufes |
| Bridge | Desacoplar una abstracción de su implementación para que varíen independientemente | Cuando tanto la abstracción como la implementación pueden cambiar | Drivers de dispositivos, renderizadores multiplataforma |
| Composite | Componer objetos en estructuras de árbol para representar jerarquías parte-todo. Tratar objetos individuales y compuestos de forma uniforme | Estructuras recursivas: menús, sistema de ficheros, UI | DOM, sistema de archivos |
| Decorator | Añadir responsabilidades dinámicamente a un objeto envolviéndolo, sin modificar su clase | Alternativa flexible a la herencia para extender funcionalidad | BufferedReader(new FileReader()), middleware |
| Facade | Proporcionar una interfaz simplificada a un subsistema complejo | Simplificar el uso de una API compleja o un conjunto de clases | APIs de alto nivel, wrappers de librerías |
| Flyweight | Compartir objetos para soportar gran cantidad de objetos de grano fino eficientemente | Miles de objetos similares con datos compartidos | Pool de caracteres, caché de objetos inmutables |
| Proxy | Proporcionar un sustituto o representante de otro objeto para controlar el acceso | Lazy loading, control de acceso, logging, caché | Proxies de red (RMI), lazy loading en JPA/Hibernate |
Examen: Adapter cambia la interfaz (hace compatible lo incompatible). Decorator añade funcionalidad (misma interfaz, más comportamiento). Proxy controla el acceso (misma interfaz, controla cuándo/cómo se accede). Facade simplifica (interfaz más simple sobre algo complejo). Composite = estructuras de árbol.
PATRONES DE COMPORTAMIENTO
| Patrón | Intención | Cuándo usarlo | Ejemplo real |
|---|---|---|---|
| Observer | Definir dependencia uno-a-muchos: cuando un objeto cambia de estado, todos sus dependientes son notificados | Eventos, suscripciones, reactive programming | Event listeners (DOM), MVC (modelo notifica a vistas) |
| Strategy | Definir una familia de algoritmos, encapsular cada uno, y hacerlos intercambiables | Múltiples algoritmos para la misma tarea (ordenación, validación, cálculo de precios) | Comparator en Java, estrategias de autenticación |
| Template Method | Definir el esqueleto de un algoritmo en la clase base; las subclases implementan los pasos específicos | Algoritmos con estructura fija pero pasos variables | HttpServlet.doGet(), frameworks con hooks |
| Command | Encapsular una solicitud como un objeto (parametrizar, encolar, deshacer) | Undo/redo, colas de comandos, operaciones diferidas | Acciones de menú, transacciones, colas de tareas |
| Iterator | Proporcionar un modo de acceder secuencialmente a los elementos de una colección sin exponer su estructura interna | Recorrer colecciones de forma uniforme | Iterator en Java, for...of en JS |
| State | Permitir que un objeto altere su comportamiento cuando cambia su estado interno (parece que cambia de clase) | Máquinas de estado, objetos con comportamiento dependiente del estado | Conexión TCP (LISTEN, ESTABLISHED, CLOSED) |
| Chain of Responsibility | Pasar una petición por una cadena de manejadores; cada uno decide si la procesa o la pasa al siguiente | Middleware, filtros, validadores en cadena | Middleware de Express/Koa, filtros de servlet |
| Mediator | Definir un objeto que encapsule cómo interactúan un conjunto de objetos (reduce acoplamiento directo) | Muchos objetos que se comunican entre sí (chat, UI compleja) | Controladores de tráfico aéreo, salas de chat |
| Memento | Capturar y almacenar el estado interno de un objeto para poder restaurarlo posteriormente | Undo/redo, snapshots, puntos de restauración | Serialización de estado, ctrl+Z |
| Visitor | Representar una operación sobre los elementos de una estructura de objetos. Permite definir nuevas operaciones sin cambiar las clases | Operaciones sobre estructuras heterogéneas (árboles AST, DOM) | Compiladores (visitor sobre AST), exportadores |
| Interpreter | Definir una gramática para un lenguaje simple y un intérprete para evaluar sentencias | Lenguajes de dominio específico (DSL), expresiones regulares, calculadoras | Evaluadores de expresiones, parsers simples |
Examen: Observer = notificación de cambios (pub/sub). Strategy = algoritmos intercambiables (composición). Template Method = esqueleto fijo, pasos variables (herencia). State vs Strategy: State cambia de comportamiento automáticamente con el estado; Strategy es elegido externamente. Command = acción como objeto (para undo, colas).
PATRONES ARQUITECTÓNICOS
MVC, MVP y MVVM
| Patrón | Componentes | Flujo de datos | Uso típico |
|---|---|---|---|
| MVC (Model-View-Controller) | Model: datos y lógica de negocio. View: presentación. Controller: gestiona la entrada del usuario y actualiza modelo/vista | Usuario → Controller → Model → View | Aplicaciones web server-side (Spring MVC, Rails, Django) |
| MVP (Model-View-Presenter) | Model: datos. View: interfaz (pasiva). Presenter: toda la lógica de presentación, manipula View directamente | View ↔ Presenter ↔ Model. View es pasiva | Android (legacy), aplicaciones de escritorio |
| MVVM (Model-View-ViewModel) | Model: datos. View: UI declarativa. ViewModel: expone datos y comandos, la View se enlaza (binding) al ViewModel | View ← (binding) → ViewModel ↔ Model | WPF, Angular, Vue, SwiftUI, Android Jetpack |
Arquitecturas por capas
| Capa | Responsabilidad | Tecnología ejemplo |
|---|---|---|
| Presentación | Interfaz de usuario, interacción | HTML/CSS/JS, React, Angular, WPF |
| Lógica de negocio | Reglas de negocio, procesamiento | Spring, EJB, .NET Core, Django |
| Acceso a datos | Persistencia, ORM, consultas a BBDD | JPA/Hibernate, Entity Framework, SQLAlchemy |
| Base de datos | Almacenamiento persistente | PostgreSQL, Oracle, MongoDB |
Otros patrones arquitectónicos
| Patrón | Descripción | Ventaja | Desventaja |
|---|---|---|---|
| Monolito | Toda la aplicación en un solo desplegable | Simple de desarrollar/desplegar/debugar inicialmente | Difícil de escalar, cambios afectan a todo |
| Microservicios | Aplicación como conjunto de servicios pequeños e independientes, cada uno con su BBDD | Escalabilidad independiente, despliegue independiente, equipos autónomos | Complejidad operacional, transacciones distribuidas, latencia de red |
| SOA (Service-Oriented Architecture) | Servicios reutilizables comunicados por ESB (Enterprise Service Bus) | Reutilización, interoperabilidad | ESB como cuello de botella, complejidad |
| Event-Driven | Componentes se comunican mediante eventos asíncronos | Desacoplamiento, escalabilidad | Difícil de debugar, eventual consistency |
| Hexagonal (Ports & Adapters) | El núcleo de negocio no depende de infraestructura; se conecta mediante puertos e adaptadores | Testabilidad, independencia de frameworks | Más clases y capas de abstracción |
| CQRS (Command Query Responsibility Segregation) | Separa el modelo de escritura (commands) del de lectura (queries) | Optimizar lectura y escritura por separado | Complejidad, sincronización |
Examen: MVC es el más preguntado — saber quién conoce a quién (Model no conoce a View directamente, Controller conoce a ambos). Microservicios vs SOA: microservicios no usan ESB centralizado (smart endpoints, dumb pipes). SOA usa ESB con lógica de routing.
PATRONES DE DISEÑO EMPRESARIALES
| Patrón | Descripción | Uso |
|---|---|---|
| Repository | Abstrae el acceso a datos detrás de una interfaz tipo colección | Desacoplar lógica de negocio de la persistencia |
| DAO (Data Access Object) | Encapsula las operaciones CRUD de una entidad específica | Capa de acceso a datos en Java EE |
| DTO (Data Transfer Object) | Objeto que transporta datos entre capas/procesos sin lógica | Reducir llamadas remotas, serialización |
| Service Layer | Capa que expone la lógica de negocio como servicios | Interfaz entre presentación y dominio |
| Unit of Work | Mantiene lista de objetos modificados en una transacción y coordina la escritura | ORM (Entity Framework, Hibernate Session) |
| Dependency Injection (DI) | Las dependencias se proporcionan externamente (constructor, setter, interfaz) | Implementar Inversión de Dependencias (SOLID D). Spring, .NET DI |
| IoC Container | Contenedor que gestiona el ciclo de vida y las dependencias de los objetos | Spring ApplicationContext, .NET ServiceProvider |
FUENTES PÚBLICAS
Este resumen ha sido elaborado íntegramente a partir de fuentes de dominio público. No se ha utilizado material con copyright de terceros ni material de preparadores.
| Fuente | Tipo | Referencia |
|---|---|---|
| Gamma, Helm, Johnson, Vlissides (1994) — "Design Patterns" (GoF) | Conocimiento público | Nombres y conceptos de patrones son de dominio público |
| Martin, R. C. — Principios SOLID | Publicaciones públicas | cleancoders.com, publicaciones técnicas |
| Fowler, M. — Patterns of Enterprise Application Architecture | Conocimiento público | Conceptos de patrones empresariales |
| Documentación de Spring Framework | Documentación oficial | spring.io/docs (Apache 2.0) |