¿Qué es Mediator?

comportamiento

Mediator define un objeto que encapsula cómo un conjunto de objetos interactúan. Evita dependencias directas entre componentes, reduciendo el acoplamiento.

  • Colleagues: componentes que emiten eventos.
  • Mediator: recibe eventos y decide qué acciones ejecutar.
  • Mejor para reglas de coordinación que crecen con el tiempo.

Diagrama

canvas
mode: mediated idle

Demo (Mediator)

notify()

Simula 2 componentes (Header y Cart) coordinados por un Mediator.

Estado loggedOut • items:0

Mediator (TS/JS)

código

Los componentes no se hablan directo; el Mediator coordina.

type EventName = 'login' | 'logout' | 'cart:add' | 'cart:clear';

interface Mediator {
  notify(sender: object, event: EventName): void;
}

class Header {
  constructor(private mediator: Mediator) {}
  clickLogin() { this.mediator.notify(this, 'login'); }
  clickLogout() { this.mediator.notify(this, 'logout'); }
}

class Cart {
  items = 0;
  constructor(private mediator: Mediator) {}
  add() { this.items++; this.mediator.notify(this, 'cart:add'); }
  clear() { this.items = 0; this.mediator.notify(this, 'cart:clear'); }
}

class AppMediator implements Mediator {
  private loggedIn = false;
  constructor(private header: Header, private cart: Cart) {}

  notify(sender: object, event: EventName) {
    if (event === 'login') this.loggedIn = true;
    if (event === 'logout') { this.loggedIn = false; this.cart.clear(); }

    if (!this.loggedIn && event === 'cart:add') {
      console.log('Denied: login required');
      return;
    }

    console.log('event:', event, 'loggedIn:', this.loggedIn, 'items:', this.cart.items);
  }
}

// wiring
let mediator!: AppMediator;
const header = new Header({ notify: (s,e) => mediator.notify(s,e) });
const cart = new Cart({ notify: (s,e) => mediator.notify(s,e) });
mediator = new AppMediator(header, cart);

header.clickLogin();
cart.add();
header.clickLogout();
class Header {
  constructor(mediator) { this.mediator = mediator; }
  clickLogin() { this.mediator.notify(this, 'login'); }
  clickLogout() { this.mediator.notify(this, 'logout'); }
}

class Cart {
  constructor(mediator) { this.mediator = mediator; this.items = 0; }
  add() { this.items++; this.mediator.notify(this, 'cart:add'); }
  clear() { this.items = 0; this.mediator.notify(this, 'cart:clear'); }
}

class AppMediator {
  constructor(header, cart) {
    this.header = header;
    this.cart = cart;
    this.loggedIn = false;
  }

  notify(sender, event) {
    if (event === 'login') this.loggedIn = true;
    if (event === 'logout') { this.loggedIn = false; this.cart.clear(); }

    if (!this.loggedIn && event === 'cart:add') {
      console.log('Denied: login required');
      return;
    }

    console.log('event:', event, 'loggedIn:', this.loggedIn, 'items:', this.cart.items);
  }
}

let mediator;
const header = new Header({ notify: (s,e) => mediator.notify(s,e) });
const cart = new Cart({ notify: (s,e) => mediator.notify(s,e) });
mediator = new AppMediator(header, cart);

header.clickLogin();
cart.add();
header.clickLogout();
En UI reales, el mediador suele ser un controller/store/event-bus. Este ejemplo es intencionalmente pequeño.