Problema

Evitar que objetos se comuniquen directamente creando un lío de dependencias difícil de mantener.

Propósito

Centraliza la comunicación entre objetos en un mediador. Los objetos no se conocen entre sí, solo conocen al mediador.

Concepto clave

Torre de control: Como en un aeropuerto - los aviones no se comunican entre sí, todos hablan con la torre de control que coordina todo el tráfico.

Casos de uso comunes

  • Interfaces gráficas complejas (formularios, diálogos)
  • Sistemas de chat y mensajería
  • Controladores de tráfico aéreo
  • Workflows y procesos de negocio
  • Sistemas de notificaciones
  • Coordinación entre microservicios

¿Quién es quién en Mediator?

Actor Lo que realmente es Ejemplo Analogía
Mediator Interfaz que define cómo coordinar DialogMediator - define notify(sender, event) “Torre de control” (interfaz)
ConcreteMediator Coordinador que conoce todos los componentes AuthenticationDialog - maneja toda la comunicación Torre de control del aeropuerto
Component Participantes que solo hablan con el mediator Button, TextBox, Checkbox Aviones (solo hablan con la torre)

Diagrama

classDiagram
    namespace MediatorPattern {
        class Mediator {
            <<interface>>
            +notify(sender, event)
        }
        
        class ConcreteMediator {
            -componentA: ComponentA
            -componentB: ComponentB
            +notify(sender, event)
        }
        
        class BaseComponent {
            -mediator: Mediator
            +setMediator(mediator)
        }
        
        class ComponentA {
            +doA()
        }
        
        class ComponentB {
            +doB()
        }
    }
    
    Mediator <|.. ConcreteMediator
    BaseComponent <|-- ComponentA
    BaseComponent <|-- ComponentB
    BaseComponent --> Mediator
    ConcreteMediator --> ComponentA
    ConcreteMediator --> ComponentB

Ejemplo práctico

classDiagram
    namespace DialogExample {
        class DialogMediator {
            <<interface>>
            +notify(sender, event)
        }
        
        class AuthenticationDialog {
            -title: String
            -loginButton: Button
            -registerButton: Button
            -usernameField: TextBox
            -passwordField: TextBox
            -rememberCheckbox: Checkbox
            +notify(sender, event)
        }
        
        class Component {
            <<abstract>>
            -mediator: DialogMediator
            +setMediator(mediator)
            +click()
            +keyPress()
        }
        
        class Button {
            -text: String
            +click()
        }
        
        class TextBox {
            -text: String
            +keyPress()
            +getText() String
            +setText(text)
        }
        
        class Checkbox {
            -checked: boolean
            +click()
            +isChecked() boolean
        }
    }
    
    DialogMediator <|.. AuthenticationDialog
    Component <|-- Button
    Component <|-- TextBox
    Component <|-- Checkbox
    Component --> DialogMediator
    AuthenticationDialog --> Button
    AuthenticationDialog --> TextBox
    AuthenticationDialog --> Checkbox

Comunicación sin mediator

graph TB
    A[Button] <--> B[TextBox1]
    A <--> C[TextBox2]
    A <--> D[Checkbox]
    B <--> C
    B <--> D
    C <--> D
    B <--> E[Label]
    C <--> E
    D <--> E
    
    F["Comunicación caótica<br/>Alto acoplamiento<br/>Difícil mantenimiento"]

Comunicación con mediator

graph TB
    A[Button] --> M[Mediator]
    B[TextBox1] --> M
    C[TextBox2] --> M
    D[Checkbox] --> M
    E[Label] --> M
    
    M --> A
    M --> B
    M --> C
    M --> D
    M --> E
    
    F["Comunicación centralizada<br/>Bajo acoplamiento<br/>Fácil mantenimiento"]

Flujo de comunicación

sequenceDiagram
    participant User
    participant Button
    participant Mediator
    participant TextBox
    participant Checkbox
    
    User->>Button: click()
    Button->>Mediator: notify(this, "click")
    
    alt Login button clicked
        Mediator->>TextBox: getText()
        TextBox-->>Mediator: username
        Mediator->>TextBox: getText()
        TextBox-->>Mediator: password
        Mediator->>Checkbox: isChecked()
        Checkbox-->>Mediator: remember
        Mediator->>Mediator: authenticate(username, password, remember)
    else Register button clicked
        Mediator->>TextBox: setText("")
        Mediator->>TextBox: setText("")
        Mediator->>Checkbox: setChecked(false)
    end

Tipos de mediadores

graph TB
    A[Mediator Types] --> B[Simple Mediator]
    A --> C[Event-Driven Mediator]
    A --> D[State-Based Mediator]
    A --> E[Command Mediator]
    
    B --> B1["Lógica directa<br/>Métodos específicos"]
    C --> C1["Basado en eventos<br/>Pub/Sub interno"]
    D --> D1["Mantiene estado<br/>Decisiones basadas en estado"]
    E --> E1["Usa Command pattern<br/>Operaciones como objetos"]

Ventajas

  • Bajo acoplamiento: Los componentes no se conocen directamente
  • Reutilización: Los componentes pueden reutilizarse en diferentes contextos
  • Centralización: La lógica de interacción está centralizada
  • Flexibilidad: Fácil cambiar las reglas de interacción

Desventajas

  • God Object: El mediator puede volverse muy complejo
  • Punto único de falla: Toda la comunicación depende del mediator
  • Complejidad: Puede ser excesivo para interacciones simples
  • Performance: Introduce overhead en la comunicación

Cuándo usar

  • Tienes un conjunto de objetos que se comunican de forma compleja
  • Las dependencias entre objetos son difíciles de entender
  • Quieres reutilizar componentes en diferentes contextos
  • Necesitas centralizar la lógica de coordinación

Cuándo NO usar

  • Las interacciones son simples y directas
  • Solo tienes pocos objetos que interactúan
  • El mediator se volvería demasiado complejo
  • La comunicación directa es más eficiente

Diferencias con otros patrones

  • vs Observer: Mediator coordina, Observer notifica
  • vs Facade: Mediator para comunicación, Facade para simplificación
  • vs Command: Mediator coordina objetos, Command encapsula operaciones