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

Payal KumariPayal Kumari
7 min read

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 ๐Ÿ‘ฉโ€๐Ÿ’ป

0
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.