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}`);
}
TODO
Visual to come