Tipos de Patrones

Soluciones probadas para problemas comunes

¿Que son los Patrones de Diseno? Son soluciones estandar para problemas comunes en el diseno de software. Son como recetas probadas que los desarrolladores pueden adaptar para resolver problemas especificos en sus aplicaciones.

Los Patrones como Herramientas de Construccion

Imagina que estas construyendo una casa. No inventarias nuevas formas de hacer cimientos o instalar ventanas cada vez, ¿verdad? Usarias tecnicas probadas por generaciones de constructores.

Los patrones de diseno son exactamente eso: tecnicas probadas para construir software de calidad.

Categorias Principales

Patrones Creacionales

Se encargan de la creacion de objetos, ayudando a hacer un sistema independiente de como se crean, componen y representan sus objetos.

Ejemplos:
Singleton: Garantiza que una clase tenga una unica instancia y proporciona un punto de acceso global a ella.
Factory Method: Define una interfaz para crear un objeto, pero deja que las subclases decidan que clase instanciar.
Builder: Separa la construccion de un objeto complejo de su representacion.

Como una fabrica de autos: diferentes lineas de produccion (patrones) para crear diferentes modelos (objetos).

Patrones Estructurales

Se ocupan de como se componen las clases y objetos para formar estructuras mas grandes y complejas.

Ejemplos:
Adapter: Permite que interfaces incompatibles trabajen juntas, como un adaptador de enchufe de viaje.
Decorator: Anade responsabilidades adicionales a un objeto dinamicamente.
Composite: Compone objetos en estructuras de arbol para representar jerarquias parte-todo.

Como construir con LEGO: diferentes piezas (objetos) se combinan para crear estructuras complejas.

Patrones de Comportamiento

Se centran en la comunicacion entre objetos, como interactuan y se distribuyen responsabilidades.

Ejemplos:
Observer: Define una dependencia uno-a-muchos entre objetos, de forma que cuando un objeto cambia de estado, todos sus dependientes son notificados.
Strategy: Define una familia de algoritmos, encapsula cada uno, y los hace intercambiables.
Command: Encapsula una solicitud como un objeto, permitiendo parametrizar clientes con diferentes solicitudes.

Como un equipo de futbol: cada jugador (objeto) tiene un rol y se comunica con otros para lograr un objetivo.

Patrones Modernos para Aplicaciones Reactivas

Circuit Breaker

Previene que una aplicacion intente repetidamente una operacion que probablemente fallara. Como un interruptor electrico que salta cuando hay sobrecarga.

Bulkhead

Aislamiento de fallos en componentes, evitando que un fallo en una parte afecte a otras. Como los compartimentos estancos de un barco.

Retry

Reintentar una operacion fallida con una estrategia inteligente (espera exponencial, jitter). Como volver a marcar un numero ocupado.

Timeout

Establecer limites de tiempo para operaciones, cancelando las que tardan demasiado. Como un cronometro para cada tarea.

Los patrones de diseno son herramientas poderosas, pero recuerda:

  • No son soluciones magicas - Deben aplicarse en el contexto adecuado
  • No abuses de ellos - A veces una solucion simple es mejor que un patron complejo
  • Conoce tu caja de herramientas - Cuantos mas patrones conozcas, mejores decisiones tomaras

Ejemplo: Patron Observer en Java

// Interfaz para los observadores
interface Observer {
    void update(String message);
}

// Implementacion concreta de un observador
// Implementacion concreta de un observador
class Cliente implements Observer {
    private String nombre;
    
    public Cliente(String nombre) {
        this.nombre = nombre;
    }
    
    @Override
    public void update(String message) {
        System.out.println(nombre + " recibio notificacion: " + message);
    }
}

// Clase observable (sujeto)
class TiendaOnline {
    private List clientes = new ArrayList<>();
    private String nombreTienda;
    
    public TiendaOnline(String nombre) {
        this.nombreTienda = nombre;
    }
    
    // Registrar un nuevo observador
    public void suscribir(Observer cliente) {
        clientes.add(cliente);
    }
    
    // Eliminar un observador
    public void desuscribir(Observer cliente) {
        clientes.remove(cliente);
    }
    
    // Notificar a todos los observadores
    public void notificarOferta(String producto) {
        String mensaje = "Nueva oferta en " + producto + " en " + nombreTienda + "!";
        for(Observer cliente : clientes) {
            cliente.update(mensaje);
        }
    }
}

// Uso del patru00f3n
public class Main {
    public static void main(String[] args) {
        TiendaOnline miTienda = new TiendaOnline("TechPeru");
        
        Cliente carlos = new Cliente("Carlos");
        Cliente maria = new Cliente("Maria");
        Cliente jose = new Cliente("Jose");
        
        miTienda.suscribir(carlos);
        miTienda.suscribir(maria);
        miTienda.suscribir(jose);
        
        miTienda.notificarOferta("Laptops Gaming");
        
        // Maria se desuscribe
        miTienda.desuscribir(maria);
        
        miTienda.notificarOferta("Smartphones");
    }
}