Parte 4: Patrones de Diseño
Soluciones Probadas a Problemas Recurrentes
En los capítulos anteriores dominamos los fundamentos de OOP (Fundamentos de la Programación Orientada a Objetos), las relaciones entre objetos (Encapsulamiento y Relaciones entre Objetos), herencia y polimorfismo (Herencia y Polimorfismo Conceptual y Herencia y Polimorfismo en Java), y el diseño por contratos (Diseño por Contratos).
Ahora aplicamos todo ese conocimiento en patrones de diseño: soluciones elegantes y probadas a problemas que aparecen una y otra vez en el desarrollo de software.
Navegación por Familias¶
Esta portada funciona como mapa general. Para entrar a cada familia y navegar sus patrones individuales:
| Familia | Enlace | Qué vas a encontrar |
|---|---|---|
| Creacionales | Ir al índice creacional | Singleton, Factory, Abstract Factory, Builder y Prototype |
| Estructurales | Ir al índice estructural | Adapter, Bridge, Composite, Decorator, Facade, Flyweight y Proxy |
| Comportamiento | Ir al índice de comportamiento | Strategy, Observer, Command, State, Template Method y otros |
Práctica de cursada¶
Parte 4 ya funciona como referencia. Para usarla como tramo de cursada, conviene trabajarla así:
| Escala | Qué hacer |
|---|---|
| Patrón individual | Leer el contexto, contrastar cuándo aplica / cuándo no aplica y resolver el mini ejercicio del final |
| Familia creacional | Cerrar con ejercicios integradores de creacionales |
| Familia estructural | Cerrar con ejercicios integradores de estructurales |
| Familia de comportamiento | Cerrar con ejercicios integradores de comportamiento |
Orden sugerido de lectura¶
| Orden | Página | Rol en el recorrido |
|---|---|---|
| 0 | Esta portada | Mapa general de la parte y criterios de uso |
| 1 | Familia Creacional | Comparar estrategias de creación |
| 2 | Singleton, Factory Method, Abstract Factory, Builder, Prototype | Recorrer los patrones creacionales |
| 3 | Ejercicios integradores de patrones creacionales | Cerrar la familia con práctica comparativa |
| 4 | Familia Estructural | Entender composición, adaptación y desacoplamiento |
| 5 | Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy | Recorrer los patrones estructurales |
| 6 | Ejercicios integradores de patrones estructurales | Cerrar la familia con decisiones de arquitectura |
| 7 | Familia de Comportamiento | Ordenar responsabilidades, algoritmos e interacciones |
| 8 | Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor | Recorrer los patrones de comportamiento |
| 9 | Ejercicios integradores de patrones de comportamiento | Cerrar la familia con comparación entre patrones |
Capítulos nucleares¶
Estos capítulos conviene dominarlos sí o sí para construir un criterio de diseño reutilizable:
| Capítulo | Por qué es nuclear |
|---|---|
| Factory Method | Fija la lógica de desacoplar creación y uso |
| Builder | Introduce construcción paso a paso y objetos complejos |
| Adapter | Instala el problema de compatibilidad entre interfaces |
| Decorator | Muestra cómo extender comportamiento sin herencia explosiva |
| Strategy | Fija la idea de algoritmos intercambiables |
| Observer | Introduce coordinación entre objetos con bajo acoplamiento |
Repaso y ampliación¶
Estas páginas cumplen mejor un rol de navegación, consolidación o profundización:
| Página | Tipo | Uso sugerido |
|---|---|---|
| Familia Creacional | Índice de familia | Usar como mapa comparativo antes o después de los patrones individuales |
| Familia Estructural | Índice de familia | Releer al decidir entre composición, adaptación y control de acceso |
| Familia de Comportamiento | Índice de familia | Usar como tabla de decisión para algoritmos, estados e interacciones |
| Singleton | Profundización | Revisar con cautela por sus trade-offs de diseño |
| Abstract Factory | Profundización | Releer cuando haga falta coherencia entre familias de objetos |
| Prototype | Profundización | Volver cuando el costo de creación o clonado sea central |
| Bridge | Profundización | Releer si aparecen jerarquías combinatorias |
| Composite | Profundización | Releer frente a árboles o estructuras recursivas |
| Facade, Flyweight, Proxy | Ampliación | Consultar según problemas concretos de simplificación, memoria o acceso |
| Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, State, Template Method, Visitor | Ampliación | Consultar según el problema dominante de control de flujo o interacción |
| Ejercicios integradores creacionales, estructurales y de comportamiento | Consolidación | Usar para cerrar cada familia con comparación y justificación |
Índice exhaustivo¶
Creacionales¶
Estructurales¶
Comportamiento¶
¿Qué son los Patrones de Diseño?¶
Definición¶
Un patrón de diseño es una solución general y reutilizable a un problema común en el diseño de software. No es código listo para usar, sino una plantilla o receta que describe cómo resolver un problema en diferentes contextos.
Los patrones de diseño, establecen un lenguaje, y aunque no se utilice exactamente como se lo describe aquí, facilita la comunicación entre desarrolladores, introduciendo conceptos reutilizables de alto nivel.
Origen e Historia¶
Los patrones de diseño en software se popularizaron con el libro de los “Gang of Four” (GoF) en 1994:
Erich Gamma
Richard Helm
Ralph Johnson
John Vlissides
Documentaron 23 patrones clasificados en tres categorías:
| Categoría | Propósito | Ejemplos |
|---|---|---|
| Creacionales | Cómo crear objetos | Factory, Singleton, Builder |
| Estructurales | Cómo componer objetos | Adapter, Decorator, Composite |
| Comportamiento | Cómo interactúan objetos | Strategy, Observer, Template |
Anatomía de un Patrón¶
Cada patrón se describe con:
Nombre: Identificador conciso y memorable
Problema: Cuándo aplicar el patrón
Solución: Estructura de clases y objetos
Consecuencias: Trade-offs y resultados
Beneficios¶
Vocabulario común: “Usemos un Observer aquí” es más claro que explicar toda la estructura
Soluciones probadas: No reinventar la rueda
Diseños flexibles: Anticipan cambios futuros
Documentación implícita: El nombre del patrón comunica la intención
Patrones Creacionales¶
Los patrones creacionales abstraen el proceso de instanciación de objetos, haciendo el sistema independiente de cómo se crean, componen y representan los objetos.
Para un análisis profundo de patrones creacionales, incluidos Singleton, Factory Method, Abstract Factory, Builder y Prototype, consultá la sección dedicada: índice de patrones creacionales.
Resumen Rápido¶
| Patrón | Propósito | Ejemplo |
|---|---|---|
| Factory Method | Delega creación a subclases | Sistema de transporte |
| Abstract Factory | Crea familias de objetos | UI multiplataforma |
| Singleton | Garantiza una única instancia | Logger, Configuración |
| Builder | Construye objetos complejos paso a paso | Constructor de pizzas |
| Prototype | Clona objetos existentes | Clonar documentos |
Patrones Estructurales¶
Los patrones estructurales se ocupan de cómo se componen las clases y objetos para formar estructuras más grandes, facilitando la comunicación entre entidades.
Para un análisis profundo de patrones estructurales, incluidos Adapter, Bridge, Composite, Decorator, Facade, Flyweight y Proxy, consultá la sección dedicada: índice de patrones estructurales.
Resumen Rápido¶
| Patrón | Propósito | Ejemplo |
|---|---|---|
| Adapter | Convierte interfaz incompatible | Integración con sistemas legacy |
| Bridge | Desacopla abstracción de implementación | Múltiples drivers |
| Composite | Estructura jerárquica uniforme | Sistema de archivos, UI |
| Decorator | Agrega responsabilidades dinámicamente | Java I/O, coffee shop |
| Facade | Interfaz simplificada a subsistema | API unificada |
| Flyweight | Comparte objetos para optimizar | Cache, pool de objetos |
| Proxy | Controla acceso a otro objeto | Lazy loading, logging |
Patrones de Comportamiento¶
Los patrones de comportamiento se ocupan de algoritmos y la asignación de responsabilidades entre objetos.
Para un análisis profundo de patrones de comportamiento, incluidos Strategy, Observer, Template Method, State, Command y otros, consultá la sección dedicada: índice de patrones de comportamiento.
Resumen Rápido¶
| Patrón | Propósito | Ejemplo |
|---|---|---|
| Strategy | Encapsula algoritmos intercambiables | Múltiples formas de ordenamiento |
| Observer | Notifica cambios a múltiples objetos | Suscripciones, eventos |
| Template Method | Define esqueleto reutilizable | Procesamiento de datos |
| State | Cambia comportamiento según estado | Máquina de estados |
| Command | Encapsula solicitudes como objetos | Undo/Redo |
| Iterator | Accede elementos secuencialmente | Recorrido de colecciones |
| Mediator | Centraliza comunicación | Chat, panel de control |
| Chain of Responsibility | Pasa solicitudes en cadena | Manejo de excepciones |
¿Cuándo Usar (y No Usar) Patrones?¶
Señales de que Necesitás un Patrón¶
| Problema | Patrón Sugerido |
|---|---|
| “Tengo muchos if/else para crear objetos” | Factory |
| “Necesito una sola instancia global” | Singleton (con cuidado) |
| “El constructor tiene demasiados parámetros” | Builder |
| “Necesito adaptar una interfaz incompatible” | Adapter |
| “Quiero agregar funcionalidad dinámicamente” | Decorator |
| “Tengo estructura de árbol/jerarquía” | Composite |
| “Tengo múltiples algoritmos intercambiables” | Strategy |
| “Objetos deben reaccionar a cambios de otro” | Observer |
| “Tengo un algoritmo con pasos variables” | Template Method |
Señales de que NO Necesitás un Patrón¶
El código es simple y funciona bien
Solo hay una implementación posible
No hay necesidad de extensibilidad
El patrón agrega complejidad sin beneficio claro
“Por si acaso lo necesite en el futuro”
Ejemplo: Combinando Patrones¶
Un sistema real suele combinar varios patrones:
// FACTORY: crea procesadores según el tipo
ProcesadorFactory factory = new ProcesadorFactory();
Procesador proc = factory.crear(tipoArchivo);
// STRATEGY: diferentes algoritmos de compresión
proc.setCompresion(new CompresionZIP());
// DECORATOR: agrega funcionalidades
proc = new ProcesadorConLog(proc);
proc = new ProcesadorConCache(proc);
// OBSERVER: notifica progreso
proc.agregarObservador(new BarraProgreso());
proc.agregarObservador(new Logger());
// TEMPLATE METHOD (interno al procesador)
proc.procesar(archivo);Resumen¶
Patrones Creacionales¶
| Patrón | Propósito |
|---|---|
| Factory | Crear objetos sin especificar clases concretas |
| Abstract Factory | Crear familias de objetos relacionados |
| Singleton | Garantizar una única instancia |
| Builder | Construir objetos complejos paso a paso |
Patrones Estructurales¶
| Patrón | Propósito |
|---|---|
| Adapter | Convertir interfaz incompatible |
| Decorator | Agregar responsabilidades dinámicamente |
| Composite | Tratar objetos y composiciones uniformemente |
Patrones de Comportamiento¶
| Patrón | Propósito |
|---|---|
| Strategy | Encapsular algoritmos intercambiables |
| Observer | Notificar cambios a múltiples objetos |
| Template Method | Definir esqueleto de algoritmo |
Principios Clave¶
Identificá el problema primero: No busques patrones, buscá soluciones
Preferí composición sobre herencia: Más flexible
Programá hacia interfaces: Más desacoplado
Evitá la complejidad innecesaria: YAGNI (You Aren’t Gonna Need It)
Próximo paso¶
Para seguir, conviene entrar a una familia concreta de patrones: creacionales, estructurales o de comportamiento.