Design Pattern 21: Mediator Pattern - Complete Guide with Real-World Chatroom Example
π Download the complete Design Pattern series code from our design_pattern repository.
π― What is the Mediator Pattern?
The Mediator Pattern is a behavioral design pattern that centralizes complex communications and control between related objects. Instead of objects referring to each other directly, they communicate through a mediator, reducing dependencies and making the system easier to maintain and extend.
Key Benefits:
- β Reduces coupling between components
- β Centralizes communication logic
- β Improves extensibility for new features
- β Simplifies maintenance
- β Scales well for large systems
π Real-World Problem: Chatroom Application
Suppose you are building a chatroom application with the following requirements:
- Users can send messages to the chatroom
- Users do not need to manage other usersβ information directly
- Adding or removing users should not affect others
Business Rules:
- All communication is managed by a central mediator
- Users interact only with the mediator, not with each other directly
- The system should be easy to extend (e.g., add message filtering, broadcasting)
ποΈ Object-Oriented Analysis (OOA)

Identified Forces:
- High Coupling - Direct communication between users increases maintenance cost
- Hard to Extend - Adding new features requires modifying multiple classes
- Increased Complexity - More users means exponentially more connections
π‘ Mediator Pattern Solution
By introducing a mediator, all communication is routed through a central object, reducing dependencies and simplifying the system.

Mediator Pattern Components:
- Mediator Interface - Defines methods for communication
- Concrete Mediator - Implements communication logic
- Colleague Interface - Represents participants
- Concrete Colleague - Implements participant behavior
π οΈ Implementation: Chatroom Example

1. Mediator Interface
interface ChatMediator {
fun sendMessage(message: String, user: User)
fun addUser(user: User)
}
2. Concrete Mediator
class ChatRoomMediator : ChatMediator {
private val users = mutableListOf<User>()
override fun sendMessage(message: String, user: User) {
users.filter { it != user }.forEach { it.receive(message) }
}
override fun addUser(user: User) {
users.add(user)
}
}
3. Colleague Interface
abstract class User(protected val mediator: ChatMediator, val name: String) {
abstract fun send(message: String)
abstract fun receive(message: String)
}
4. Concrete Colleague
class ChatUser(mediator: ChatMediator, name: String) : User(mediator, name) {
override fun send(message: String) {
println("$name sends: $message")
mediator.sendMessage(message, this)
}
override fun receive(message: String) {
println("$name receives: $message")
}
}
5. Client Code
fun main() {
val chatMediator = ChatRoomMediator()
val user1 = ChatUser(chatMediator, "Alice")
val user2 = ChatUser(chatMediator, "Bob")
val user3 = ChatUser(chatMediator, "Charlie")
chatMediator.addUser(user1)
chatMediator.addUser(user2)
chatMediator.addUser(user3)
user1.send("Hello, everyone!")
user2.send("Hi, Alice!")
}
Expected Output:
Alice sends: Hello, everyone!
Bob receives: Hello, everyone!
Charlie receives: Hello, everyone!
Bob sends: Hi, Alice!
Alice receives: Hi, Alice!
Charlie receives: Hi, Alice!
π Mediator Pattern vs Alternative Approaches
Approach | Pros | Cons |
---|---|---|
Mediator Pattern | β
Reduces coupling β Centralizes logic | β Mediator can become complex β Single point of failure |
Direct Communication | β Simple for small systems | β High coupling β Hard to extend |
Event Bus | β Decoupled communication | β Harder to trace logic β Global state |
π― When to Use the Mediator Pattern
β Perfect For:
- Chatroom systems
- GUI component communication
- Event-driven architectures
- Workflow engines
- Complex system coordination
β Avoid When:
- Simple, small systems
- Mediator logic becomes too complex
π§ Advanced Mediator Pattern Implementations
- Message Filtering: Add logic in mediator to filter or transform messages
- Broadcasting: Support for broadcasting to all or specific users
- Logging and Monitoring: Centralize logging in mediator
- Dynamic User Management: Add/remove users at runtime
π Real-World Applications
- Chatroom and messaging apps
- Air traffic control systems
- GUI frameworks (dialog coordination)
- Workflow and process engines
π¨ Common Pitfalls and Best Practices
- Avoid making the mediator too complex (split responsibilities if needed)
- Document all communication flows
- Use clear naming for mediator methods
π Related Articles
- Design Pattern 1: Object-Oriented Concepts
- Design Pattern 2: Design Principles
- Command Pattern
- Observer Pattern
- State Pattern
β Conclusion
Through the Mediator Pattern, we successfully reduced coupling between users and centralized communication logic, making the system more maintainable and extensible.
Key Advantages:
- π― Reduces coupling
- π§ Centralizes communication logic
- π Easy extension
- π‘οΈ Maintainability
- β‘ Scalability
Design Principles Followed:
- Single Responsibility Principle (SRP): Mediator handles communication
- Open-Closed Principle (OCP): Add new features without modifying users
- Donβt Repeat Yourself (DRY): Centralize logic in mediator
Perfect For:
- Chatroom systems
- GUI frameworks
- Workflow engines
The Mediator Pattern provides an elegant solution for managing complex communications in scalable systems!
π‘ Pro Tip: If the mediator becomes too complex, consider splitting it into multiple mediators for different concerns.
π Stay Updated: Follow our Design Pattern series for more software architecture insights!
Enjoy Reading This Article?
Here are some more articles you might like to read next: