← Mediator lesson
Lab

Mediator

// What a panel can tell the desk.
type DeskEvent = { kind: 'cleared' | 'line-failed'; callerId: string };

// The one thing every panel knows: where to report.
interface Desk {
  notify(event: DeskEvent): void;
}

// Shows the host who is on air.
class HostCue {
  shown = 'none';
  show(callerId: string) {
    this.shown = callerId;
  }
}

// Opens a caller's phone line to the studio. One line is faulty.
class AudioBoard {
  line = 'none';
  desk: Desk;
  faulty: string;
  constructor(desk: Desk, faulty: string) {
    this.desk = desk;
    this.faulty = faulty;
  }
  open(callerId: string) {
    if (callerId === this.faulty) {
      this.line = 'none';
      this.desk.notify({ kind: 'line-failed', callerId });
      return;
    }
    this.line = callerId;
  }
}

// Clears a caller to go on air.
class Screener {
  desk: Desk;
  constructor(desk: Desk) {
    this.desk = desk;
  }
  clear(callerId: string) {
    this.desk.notify({ kind: 'cleared', callerId });
  }
}

// The mediator: the only place that knows how the panels work together.
class CallInDesk implements Desk {
  host = new HostCue();
  board: AudioBoard;
  constructor(faulty: string) {
    this.board = new AudioBoard(this, faulty);
  }
  notify(event: DeskEvent) {
    if (event.kind === 'cleared') {
      this.host.show(event.callerId);
      this.board.open(event.callerId);
    } else if (this.host.shown === event.callerId) {
      this.host.show('none');
    }
  }
}

const desk = new CallInDesk('caller-22');
const screener = new Screener(desk);

for (const callerId of ['caller-17', 'caller-22']) {
  screener.clear(callerId);
  const cue = desk.host.shown;
  const line = desk.board.line;
  const agree = cue === line;
  console.log(`${callerId}: cue=${cue} line=${line} agree=${agree}`);
}