๐ Week-7 (Day-5) - How to Create a Chat Room Using the Mediator Design Pattern: UML and Coding Guide

Table of contents

NOTE: - I started my 8-week system design journey with Coder Army. I will be journaling every day, recording what I learn, reflecting on it, and sharing it with my network to help newcomers to system design.
Namaste developers! ๐
Welcome to another power-packed day of the #8WeeksLLDChallenge โ and today weโre diving into something that every large system needs but no one talks about enough โ the Mediator Design Pattern!
Aaj ka topic hai Chat Room System โ but with a twist!
Instead of letting every user talk directly to each other (which creates a communication mess, weโll learn how to design a clean, scalable system using the Mediator Design Pattern.
๐ What is Mediator Design Pattern?
"Defines an object that encapsulates how a set of objects interact and promotes loose coupling by preventing them from referring to each other directly."
Definition: Mediator Pattern centralizes complex communications and control between related objects (called colleagues), so they don't communicate directly with each other.
(Hindi: Mediator Design Pattern ek central hub create karta hai jiske through sab users communicate karte hain. Iss se har class independent hoti hai aur direct dependency nahi hoti.)
๐ Real-Life Analogy
Classroom Example: Imagine a classroom where all students communicate only through the teacher โ if someone has a question or wants to answer, they tell the teacher, and the teacher communicates it to everyone else.
(Hindi: Socho ek classroom hai jahan sab students sirf teacher ke through baat karte hain โ kisi ko question poochhna ho, ya answer dena ho, wo teacher ko bolte hain aur teacher sabko communicate karta hai.)
That teacher is the Mediator!
(Hindi: Agar sab students directly baat karte toh sab confuse ho jaate โ lekin teacher ke through sabka communication ekdum smooth hota hai!)
๐ Problem Without Mediator (Tight Coupling)
If we design without a mediator, then each user would have to connect with every other user manually.
(Hindi: Agar hum bina mediator ke design karein, toh har user ko har doosre user ke saath manually connect karna padta hai:
For N users, we need Nร(Nโ1)/2 connections
Har user ke paas apna mute logic, message logic
Code duplication and hard to maintain
Example Without Mediator:
User rohan = new User("Rohan");
User neha = new User("Neha");
User mohan = new User("Mohan");
rohan.addPeer(neha);
rohan.addPeer(mohan);
... and so on
This becomes complex as your user count increases.
๐ Solution: Use Mediator Design Pattern
Now we introduce a mediator โ a central controller that:
Registers users
Passes messages between them
Handles private messaging and mute features
Ek tarah se yeh mediator pura system manage karta hai, bina users ko directly ek dusre se connect kare.
๐ Benefits:
Loose coupling
Reusability
Easy to manage
Scalability
๐ Components in Mediator Pattern
๐ IMediator
Interface
registerColleague(Colleague c)
send(from, msg)
sendPrivate(from, to, msg)
๐ Colleague
(Abstract User)
- Har user mediator ke reference se kaam karta hai
๐ ChatMediator
(Concrete Mediator)
- Handles registration, broadcast, private messaging, and mute
๐ User
(Concrete Colleague)
Har user ka name hota hai
Messages ko send/receive karta hai
๐ UML Diagram
๐ Code
import java.util.*;
// โโโโโโโโโโโโโโโ Mediator Interface โโโโโโโโโโโโโโโ
interface IMediator {
void registerColleague(Colleague c);
void send(String from, String msg);
void sendPrivate(String from, String to, String msg);
}
// โโโโโโโโโโโโโโโ Colleague Interface โโโโโโโโโโโโโโโ
abstract class Colleague {
protected IMediator mediator;
public Colleague(IMediator m) {
mediator = m;
mediator.registerColleague(this);
}
public abstract String getName();
public abstract void send(String msg);
public abstract void sendPrivate(String to, String msg);
public abstract void receive(String from, String msg);
}
// Simple Pair class
class Pair<T, U> {
public final T first;
public final U second;
public Pair(T first, U second) {
this.first = first;
this.second = second;
}
}
// โโโโโโโโโโโโโโโ Concrete Mediator โโโโโโโโโโโโโโโ
class ChatMediator implements IMediator {
private List<Colleague> colleagues;
private List<Pair<String, String>> mutes; // (muter, muted)
public ChatMediator() {
colleagues = new ArrayList<>();
mutes = new ArrayList<>();
}
public void registerColleague(Colleague c) {
colleagues.add(c);
}
public void mute(String who, String whom) {
mutes.add(new Pair<>(who, whom));
}
public void send(String from, String msg) {
System.out.println("[" + from + " broadcasts]: " + msg);
for (Colleague c : colleagues) {
// Don't send msg to itself.
if (c.getName().equals(from)) {
continue;
}
boolean isMuted = false;
// Ignore if person is muted
for (Pair<String, String> p : mutes) {
if (from.equals(p.second) && c.getName().equals(p.first)) {
isMuted = true;
break;
}
}
if (!isMuted) {
c.receive(from, msg);
}
}
}
public void sendPrivate(String from, String to, String msg) {
System.out.println("[" + from + "โ" + to + "]: " + msg);
for (Colleague c : colleagues) {
if (c.getName().equals(to)) {
for (Pair<String, String> p : mutes) {
//Dont send if muted
if (from.equals(p.second) && to.equals(p.first)) {
System.out.println("\n[Message is muted]\n");
return;
}
}
c.receive(from, msg);
return;
}
}
System.out.println("[Mediator] User \"" + to + "\" not found]");
}
}
// โโโโโโโโโโโโโโโ Concrete Colleague โโโโโโโโโโโโโโโ
class User extends Colleague {
private String name;
public User(String n, IMediator m) {
super(m);
name = n;
}
@Override
public String getName() {
return name;
}
@Override
public void send(String msg) {
mediator.send(name, msg);
}
@Override
public void sendPrivate(String to, String msg) {
mediator.sendPrivate(name, to, msg);
}
@Override
public void receive(String from, String msg) {
System.out.println(" " + name + " got from " + from + ": " + msg);
}
}
// โโโโโโโโโโโโโโโ Demo โโโโโโโโโโโโโโโ
public class MediatorPattern {
public static void main(String[] args) {
ChatMediator chatRoom = new ChatMediator();
User user1 = new User("Rohan", chatRoom);
User user2 = new User("Neha", chatRoom);
User user3 = new User("Mohan", chatRoom);
// Rohan mutes Mohan
chatRoom.mute("Rohan", "Mohan");
// broadcast from Rohan
user1.send("Hello Everyone!");
// private from Mohan to Neha
user3.sendPrivate("Neha", "Hey Neha!");
}
}
import java.util.*;
// Each User knows *all* the others directly.
// If you have N users, you wind up wiring N*(Nโ1)/2 connections,
// and every new feature (mute, private send, logging...) lives in User too.
class User {
private String name;
private List<User> peers;
private List<String> mutedUsers;
public User(String n) {
name = n;
peers = new ArrayList<>();
mutedUsers = new ArrayList<>();
}
// must manually connect every pair โ N^2 wiring
public void addPeer(User u) {
peers.add(u);
}
// duplication: everyone has its own mute list
public void mute(String userToMute) {
mutedUsers.add(userToMute);
}
// broadcast to all peers
public void send(String msg) {
System.out.println("[" + name + " broadcasts]: " + msg);
for (User peer : peers) {
// if they have muted me dont send.
if(!peer.isMuted(name)) {
peer.receive(name, msg);
}
}
}
public boolean isMuted(String userName) {
for(String name : mutedUsers) {
if(name.equals(userName)) {
return true;
}
}
return false;
}
// private send - duplicated in every class
public void sendTo(User target, String msg) {
System.out.println("[" + name + "โ" + target.name + "]: " + msg);
if(!target.isMuted(name)) {
target.receive(name, msg);
}
}
public void receive(String from, String msg) {
System.out.println(" " + name + " got from " + from + ": " + msg);
}
}
public class WithoutMediator {
public static void main(String[] args) {
// create users
User user1 = new User("Rohan");
User user2 = new User("Neha");
User user3 = new User("Mohan");
// wire up peers (each knows each other) โ n*(n-1)/2 connections
user1.addPeer(user2);
user2.addPeer(user1);
user1.addPeer(user3);
user3.addPeer(user1);
user2.addPeer(user3);
user3.addPeer(user2);
// mute example: Mohan mutes Rohan (Hence Rohan add Mohan to its muted list).
user1.mute("Mohan");
// broadcast
user1.send("Hello everyone!");
// private
user3.sendTo(user2, "Hey Neha!");
}
}
๐ Advantages of Mediator Design Pattern
๐น Centralized Control
๐น Reduces Complexity
๐น Makes adding new features easy
๐น Loosely coupled and testable code
๐ Where Can You Use Mediator Pattern?
Chat applications (like WhatsApp, Slack)
Air Traffic Control systems
Event Managers in GUI libraries
Gaming lobby systems
(Hindi: Jahan multiple objects ek dusre se baat karte hain โ mediator pattern ek boss ki tarah control leta hai!)
๐ Final Thoughts
Design Patterns are like magic spells for engineers
Mediator pattern ek real-world friendly aur scalable design approach deta hai โ jise use karke hum chat room jaise complex interactions ko asaan aur manageable bana sakte hain.
Next time jab chat system banana ho ya multiple classes ke beech coordination chahiye ho โ remember this: Use a Mediator!
System Design is not just for interviews โ itโs a real skill for clean code and better architecture.
Week - 7 (Day-5) Completed โ System Design
NOTE : - A big thanks to my mentors Rohit Negi Sir and Aditya Sir for launching this amazing 8-week course absolutely free on YouTube via CoderArmy9 :- youtube.com/@CoderArmy9 . ๐
๐ Share this blog with your connections! Letโs keep learning, growing, and supporting one another on this journey. ๐
โ๏ธ Payal Kumari ๐ฉโ๐ป
Jai Hind ๐ฎ๐ณ | #CoderArmy #LearningInPublic #SystemDesign #TechForAll #MentorshipMatters #8weeksLLdChallenge #LowLevelDesign #LLD ๐ฉโ๐ป
Subscribe to my newsletter
Read articles from Payal Kumari directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Payal Kumari
Payal Kumari
I'm a passionate full-stack developer with a strong foundation in the MERN stackโbuilding and maintaining scalable web applications using React.js, Node.js, and Next.js. My journey in open source began with Hacktoberfest 2023, where I made four impactful pull requests that sparked a love for collaborative coding, global learning, and open knowledge sharing. Since then, Iโve contributed to and mentored projects in top open source programs like GSSoCโ24, SSOCโ24, and C4GTโ24. As a Google Gen AI Exchange Hackathon โ24 Finalist and Googleโs Women Techmakers (WTM) Ambassador, Iโve been privileged to support diverse communities in building meaningful tech solutions. My work as a Top 50 Mentor for GSSoC โ24 reflects my commitment to nurturing new talent in tech. Beyond development, I serve as a Student Career Guide, Profile Building Expert & Evangelist at Topmate.io, where I conduct workshops, guide students through resume building and career strategy, and help mentees navigate open source and tech careers. Recognized among the Top 5% of mentors and featured on โTopmate Discover,โ I take pride in making mentorship accessible and impactful. My technical voice has also been acknowledged by LinkedIn, where Iโve earned the Top Voice badge seven times in domains like web development, programming, and software engineering. In addition, I hold LinkedIn Golden Badges for Research Skills, Interpersonal Skills, Critical Thinking, and Teamworkโsignaling a well-rounded approach to both individual contribution and team collaboration. Graduating with an MCA from Chandigarh University in 2023, Iโve continued to fuel my curiosity by writing technical articles and sharing practical MERN stack insights across platforms. Whether itโs building polished UIs, optimizing backend performance, or guiding a mentee through their first pull request, Iโm driven by the power of community and continuous learning. Letโs connect! I'm open to collaborations, mentorship, or building something impactful together. Reach out to me at kumaripayal7488@gmail.com or visit my profile on Topmate.io.