¿Qué es Mediator?
comportamientoMediator 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ódigoLos 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.