Problema

Simplificar el acceso a un subsistema complejo proporcionando una interfaz unificada y fácil de usar.

Propósito

Proporcionar una interfaz unificada para un conjunto de interfaces en un subsistema. Define una interfaz de alto nivel que hace que el subsistema sea más fácil de usar, ocultando su complejidad interna.

Casos de uso comunes

  • Home automation: Un botón “Ver película” controla audio, video y luces
  • APIs unificadas: Un endpoint que coordina múltiples microservicios
  • Frameworks: jQuery simplifica el DOM complejo del navegador
  • Servicios de alto nivel: Un servicio que coordina base de datos, cache y logs
  • Integraciones: Un cliente que simplifica APIs complejas de terceros

¿Quién es quién en Facade?

Actor Lo que realmente es Ejemplo Analogía
Facade Interfaz simplificada que coordina HomeTheaterFacade - ofrece startMovie() Recepcionista de hotel (interfaz simple)
Subsystem Classes Clases complejas con responsabilidades específicas AudioSystem, VideoSystem, LightingSystem Limpieza, Cocina, Mantenimiento
Client Usuario que solo conoce la interfaz simple Cliente que llama theater.startMovie() Huésped (solo habla con recepcionista)

Clave: El Facade NO reemplaza el subsistema, solo lo simplifica

Diagrama

classDiagram
    namespace FacadePattern {
        class Facade {
            -subsystem1: SubsystemA
            -subsystem2: SubsystemB
            -subsystem3: SubsystemC
            +operation()
            +complexOperation()
        }
        
        class SubsystemA {
            +operationA1()
            +operationA2()
        }
        
        class SubsystemB {
            +operationB1()
            +operationB2()
        }
        
        class SubsystemC {
            +operationC1()
            +operationC2()
        }
        
        class Client {
            +clientCode()
        }
    }
    
    Facade --> SubsystemA
    Facade --> SubsystemB
    Facade --> SubsystemC
    Client --> Facade

Ejemplo práctico

classDiagram
    namespace HomeTheaterExample {
        class HomeTheaterFacade {
            -audio: AudioSystem
            -video: VideoSystem
            -lights: LightingSystem
            +startMovie()
            +endMovie()
        }
        
        class AudioSystem {
            +turnOn()
            +setVolume(int)
        }
        
        class VideoSystem {
            +turnOn()
            +setInput(String)
        }
        
        class LightingSystem {
            +dimLights()
        }
    }
    
    HomeTheaterFacade --> AudioSystem
    HomeTheaterFacade --> VideoSystem
    HomeTheaterFacade --> LightingSystem

Sin Facade vs Con Facade

// Sin Facade (cliente hace todo)
audio.turnOn();
audio.setVolume(70);
video.turnOn();
video.setInput("HDMI1");
lights.dimLights();

// Con Facade (una sola llamada)
theater.startMovie();

Ventajas

  • Simplicidad: Interfaz simple para subsistema complejo
  • Desacoplamiento: Clientes no dependen de clases del subsistema
  • Flexibilidad: Cambios internos no afectan clientes
  • Organización: Agrupa funcionalidades relacionadas

Desventajas

  • Limitaciones: Puede no exponer toda la funcionalidad del subsistema
  • God Object: El facade puede volverse demasiado grande
  • Rigidez: Puede limitar la flexibilidad si es muy específico
  • Dependencia: Crea un punto único de falla

Cuándo usar

  • Quieres proporcionar una interfaz simple a un subsistema complejo
  • Hay muchas dependencias entre clientes y clases de implementación
  • Quieres estructurar un subsistema en capas
  • Necesitas un punto de entrada unificado para múltiples servicios

Cuándo NO usar

  • El subsistema ya es simple
  • Los clientes necesitan acceso directo a funcionalidades específicas
  • El facade se volvería demasiado complejo
  • Solo tienes un subsistema simple