Mediator Design Pattern

The Mediator Design Pattern reduce communication complexity between objects through mediator object. It decouple the direct interaction between objects by providing a mediator, that facilitates the communication between the objects. Instead of classes communicating directly with each other, classes send messages to the mediator and the mediator sends these messages to the other classes.

When an object wants to communicate with another object(s), it does not interact with other object(s) directly. Instead, it sends its message to the mediator object whose responsibility is to route the messages to destination object(s).

This pattern is particularly useful in scenarios where a group of objects interact in complex ways and need to be decoupled for better maintainability and extensibility. In this tutorial, we will explore the Mediator Design Pattern in Java. We'll discuss its structure, implementation, and usage. Additionally, we'll delve into best practices for implementing the pattern and highlight its advantages.

Real life Example

  • In Air traffic controller. All incoming or outgoing flights don't communicate with each other directly, Instead they communicate with airport's air traffic controller.
  • Group chat room. One member of group sends message to chat server, then it is chat server's responsibility to propagate this message to all other members of the group.

Structure of the Factory Design Pattern

  • Mediator Interface : Interface used by Colleagues to interact with Mediator.
  • Concrete Mediator : Implements Mediator Interface and maintains a list of Colleagues communicating with each other. It facilitates the communication between Colleages by routing their messages to destination colleague(s). It is the communication center for the Colleagues.
  • Colleague(s) : Object(s) communicating with other object(s). It contains a reference of Mediator object.

Advantages of Mediator Design Pattern

The Mediator Design Pattern offers several advantages that contribute to the development of flexible and maintainable software systems:
  • Decoupling of Colleagues : One of the primary advantages of the Mediator Design Pattern is the decoupling of colleagues. Colleagues do not have direct references to each other, reducing dependencies and promoting a more modular design.

  • Improved Maintainability : The decoupling achieved through the mediator promotes improved maintainability. Changes to one colleague do not require modifications to other colleagues or the mediator, making the system more resilient to changes.

  • Centralized Communication : The mediator centralizes communication logic. This centralization simplifies the overall system design by providing a single point of control for coordinating interactions between colleagues.

  • Promotion of Reusability : The mediator can be reused in different scenarios. As long as the communication protocol between colleagues remains consistent, the same mediator implementation can be employed in various contexts.

  • Easier Extensibility : The Mediator Design Pattern makes the system more extensible. Introducing new colleagues or modifying existing ones is less challenging because changes are localized to the mediator rather than being scattered throughout the system.

  • Simplified Communication : Colleagues communicate through the mediator, which simplifies the communication pathways. This simplicity reduces the chances of communication-related bugs and makes it easier to understand and debug the system.

  • Promotion of Loose Coupling : Loose coupling is a key benefit of the Mediator Design Pattern. Colleagues only interact with the mediator, and changes to one colleague do not cascade to other colleagues. This loose coupling improves the overall stability of the system.

  • Centralized Control : The mediator provides centralized control over the communication flow. This centralized control can be beneficial in scenarios where specific rules or policies need to be enforced during communication between colleagues.

  • Support for Complex Systems : The Mediator Design Pattern is particularly useful in complex systems where multiple objects interact in intricate ways. It provides a structured approach to managing these interactions, reducing the complexity of the overall system.
By leveraging these advantages, the Mediator Design Pattern becomes a valuable tool for promoting a modular and maintainable architecture. Its ability to centralize communication and reduce dependencies between components makes it suitable for scenarios where a group of objects needs to collaborate in a cohesive yet loosely coupled manner.

When we should use Mediator Pattern

  • When we want to simplify the communication between lots of object interacting with each other.
  • When we want to centrally manage all communication between Colleagues.

Implementation of Mediator Design Pattern

Here, we will implement a chat group using mediator pattern. ChatServer is the Mediator interface class that is used by the char participants to interact with mediator object.

Mediator Design Pattern UML Diagram
public interface ChatServer {
    public void addUser(Participant user);
    public void sendMessage(Participant user, String message);

ChatServerMediator is the concrete implementation of ChatServer interface. It will act as a mediator object, whose primary responsibility is to route messages between participants.
import java.util.List;
import java.util.ArrayList;

public class ChatServerMediator implements ChatServer {
    private List<Participant> participantList;
    public ChatServerMediator(){
       participantList = new ArrayList<Participant>();
    public void addUser(Participant user){
    public void sendMessage(Participant user, String message){
      for(Participant p : participantList){
         if(p != user){
            p.receiveMessage(message, user);

Participants is the member of the chat group, communication with each other by calling mediator(ChatServerMediator).
public class Participant {
    private String userName;
    private ChatServer charServerMediator;
    public Participant(String name){
        this.userName = name;
    public String getUserName(){
     return userName;
    public void joinChatGroup(ChatServer chatGroup){
     charServerMediator = chatGroup;
    public void sendMessage(String message){
     System.out.println(userName +", Sending this message : \""
            + message + "\"");
     charServerMediator.sendMessage(this, message);
    public void receiveMessage(String message, Participant user){
     System.out.println(userName + ", Received : \"" + message 
            + "\", From : " + user.userName);

MediatorPatternExample will simulate the communication between participants using ChatServerMediator.
public class MediatorPatternExample {
    public static void main (String args[]){
 ChatServer chatServer = new ChatServerMediator();
 Participant jack = new Participant("Jack");
 Participant george = new Participant("George");
 Participant emilly = new Participant("Emilly");
 // Jack is sending message
 jack.sendMessage("Hi Everyone, I am Jack");
 // Emilly replying to Jack
 emilly.sendMessage("Hi Jack, How are you");


Jack, Sending this message : "Hi Everyone, I am Jack"
George, Received : "Hi Everyone, I am Jack", From : Jack
Emilly, Received : "Hi Everyone, I am Jack", From : Jack
Emilly, Sending this message : "Hi Jack, How are you"
Jack, Received : "Hi Jack, How are you", From : Emilly
George, Received : "Hi Jack, How are you", From : Emilly

Best Practices of Mediator Design Pattern

To ensure a robust and maintainable implementation of the Mediator Design Pattern, follow these best practices:
  • Design the mediator interface with a clear and concise set of methods for communication between colleagues. Avoid adding unnecessary methods that may lead to a bloated interface.

  • Colleagues should not be aware of each other's existence. They communicate through the mediator, and changes to one colleague should not impact others. This independence simplifies maintenance and extensibility.

  • The mediator should encapsulate the communication logic between colleagues. Colleagues should not have direct references to each other, promoting loose coupling and independence.

  • If the mediator needs to maintain state information, manage it carefully to avoid becoming a monolithic controller. Consider using a separate state manager or delegating state management to the colleagues when appropriate.

  • Define interfaces for colleagues to ensure a consistent communication protocol. Concrete colleagues implement these interfaces, and the mediator works with the interfaces rather than concrete implementations.

  • Design the mediator to be reusable across different scenarios. Avoid hard-coding specific colleague interactions, making the mediator adaptable to different contexts.

  • Avoid creating a "God" mediator that handles all interactions in the system. Instead, consider creating multiple mediators with specific responsibilities, promoting a more modular and maintainable design.

  • Define a consistent approach to error handling in the mediator. Decide whether errors during communication should be handled centrally in the mediator or whether individual colleagues should handle errors.

  • Use clear and meaningful names for mediator methods and colleagues. Naming conventions such as sendMessage and receiveMessage provide clarity regarding the purpose of the methods.

  • Document the mediator-related classes and methods. Clearly specify the responsibilities of the mediator, colleagues, and any other related components. Provide examples or documentation on how to extend or modify the mediator for different scenarios.
Related Topics
Memento Design Pattern
Bridge Design Pattern
Interpreter Design Pattern
Facade Design Pattern
Observer Design Pattern
List of Design Patterns