Mediator Pattern
Reduce coupling by centralizing complex communications
Pattern Overview
🤝 Mediator Pattern
The Mediator Pattern defines how objects interact with each other. Instead of objects communicating directly, they communicate through a central mediator, reducing coupling between components.
Core Concepts
🔹 Mediator Interface - Defines communication contract
🔹 Concrete Mediator - Implements interaction logic between colleagues
🔹 Colleague Classes - Components that communicate via mediator
🔹 Centralized Control - All interactions flow through mediator
Real-World Applications
Chat Systems - Users communicate through chat room mediator Air Traffic Control - Aircraft coordinate through ATC mediator UI Forms - Form components interact through form mediator Event Systems - Publishers and subscribers communicate via event busCommunication Patterns
Before Mediator: Objects have direct references to each other (N×N complexity) After Mediator: Objects only know about mediator (N×1 complexity) Result: Reduced coupling and centralized interaction logicImplementation Benefits
✅ Loose coupling - Colleagues don't reference each other directly
✅ Centralized control - Interaction logic in one place
✅ Reusable components - Colleagues can be used in different contexts
✅ Easy to extend - Add new interaction patterns in mediator
Examples:
const { chatRoom, alice, bob, moderator } = createChatRoom();
alice.send('Hello everyone!');
bob.send('Hi Alice!');
moderator.muteUser('Bob');
alice.send('How is everyone doing?');
console.log(`Total users: ${chatRoom.getUserCount()}`);Bob received from Alice: "Hello everyone!"
ModeratorMike (moderator) received from Alice: "Hello everyone!"
Alice received from Bob: "Hi Alice!"
ModeratorMike (moderator) received from Bob: "Hi Alice!"
ModeratorMike muted Bob
Alice received from Bob: "How is everyone doing?"
ModeratorMike (moderator) received from Alice: "How is everyone doing?"
Total users: 4const { atc, flight101, privatePlane } = createAirport();
console.log(flight101.requestLanding());
console.log(privatePlane.requestLanding());
console.log(flight101.requestTakeoff());ATC to AA101: Cleared to land on Runway 1
ATC to N123AB: Cleared to land on Runway 2
ATC to AA101: Cleared for takeoff on Runway 1const form = createAuthForm();
const { username, password, loginButton } = form.getComponents();
console.log(`Login enabled: ${loginButton.isEnabled()}`);
username.setValue('john');
console.log(`Login enabled: ${loginButton.isEnabled()}`);
password.setValue('secret');
console.log(`Login enabled: ${loginButton.isEnabled()}`);Login enabled: false
Login enabled: false
Login enabled: trueConcepts
Complexity Analysis
Implementation
chat-system
// Mediator interface
interface ChatMediator {
sendMessage(message: string, user: ChatUser): void;
addUser(user: ChatUser): void;
removeUser(user: ChatUser): void;
}
// Concrete mediator - Chat Room
class ChatRoom implements ChatMediator {
private users: ChatUser[] = [];
addUser(user: ChatUser): void {
this.users.push(user);
console.log(`${user.getName()} joined the chat`);
}
removeUser(user: ChatUser): void {
const index = this.users.indexOf(user);
if (index !== -1) {
this.users.splice(index, 1);
console.log(`${user.getName()} left the chat`);
}
}
sendMessage(message: string, sender: ChatUser): void {
this.users.forEach(user => {
if (user !== sender) {
user.receive(message, sender.getName());
}
});
}
getUserCount(): number {
return this.users.length;
}
}
// Colleague classes
abstract class ChatUser {
constructor(
protected name: string,
protected mediator: ChatMediator
) {
this.mediator.addUser(this);
}
abstract send(message: string): void;
abstract receive(message: string, from: string): void;
getName(): string {
return this.name;
}
}
class RegularUser extends ChatUser {
send(message: string): void {
console.log(`${this.name} sends: "${message}"`);
this.mediator.sendMessage(message, this);
}
receive(message: string, from: string): void {
console.log(`${this.name} received from ${from}: "${message}"`);
}
}