design·lab

Behavioral pattern

Mediator

Components stop talking to each other directly — they talk to one mediator, and it decides who reacts to what.

✗ The problem

Every component knows every other component

The checkbox reaches into the email field; the email field reaches into the button — and back again. A tangled many-to-many web.

class GuestCheckbox {
  onChange() {
    emailField.disabled = !this.checked;   // knows EmailField
    submitButton.refresh();             // knows Button
  }
}
class EmailField {
  onInput() {
    submitButton.refresh();             // knows Button too
    guestCheckbox.syncLabel();          // ← new link? edit here
  }
}
Checkbox
Email field
Submit

…plus Checkbox ↔ Submit — every pair wired directly (N×N).

Adding one more component means editing many others just to wire it in.
✓ The pattern

Route every interaction through one hub

Each component only calls this.mediator.notify(this, event). The mediator holds the rules and updates whoever needs updating.

class DialogMediator {
  notify(sender, event) {
    // central rules: who reacts to what
  }
}

// each component:
this.mediator.notify(this, 'change');
Mediator
notify()
Checkbox
Email field
Submit
✓ See it live

A dialog, wired only through the mediator

Toggle Guest checkout or type an email. Every change is routed through notify() — no field ever touches another directly.

Checkbox
Mediator
Email field
Waiting for input…
✓ Takeaway

One hub for coordination logic

  • N connections, not N×N: every component talks only to the mediator.
  • Add / remove a component by teaching the mediator, not every peer.
  • Differs from Observer: a mediator holds coordination logic — Observer is just a blind broadcast.
  • Caution: a mediator that keeps absorbing rules can grow into a god-object.
🎯 Principle applied: Mediator cuts coupling to a single hub and gives interaction logic one home (SRP), so components don't depend on each other.