Mediator Pattern is a behavioral design pattern that reduce chaotic dependencies between objects. This is achieved by creating a mediator object that takes care of the interaction between dependent objects. Consequently, all the communication goes through the mediator.

Intent

  • Define an object that encapsulates how a set of objects interact.
  • Promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
  • Design an intermediary to decouple many peers.
  • Mediator helps to facilitate the interaction between objects in a manner in that objects are not aware of the existence of other objects.

Implementation

This pattern defines a Mediator object that encapsulates the interaction between a set of objects. Following are the participants:

  • Mediator : Defines the interface for communication between Colleague objects
  • Colleague : Defines the interface for communication with other Colleagues through its Mediator
  • ConcreteMediator : Coordinates communication between Colleague
  • ConcreteColleague : Communicates with other Colleagues through its Mediator
UML of Mediator Design Pattern
UML of Mediator Design Pattern

Example

Below example is simulating a chat application where users can send messages to other users in one to one fashion.

// Mediator Interface
public interface Mediator 
{
  public void sendMessage(String msg, int userId);
  void addColleague(User user);
}

// Concrete Mediator 
public class ChatRoom implements Mediator {
 
  private Map<Integer, User> mUsers = new HashMap<>();

  @Override
  public void sendMessage(String msg, int userId) 
  {
    User u = mUsers.get(userId);
    u.receive(msg);
  }

  @Override
  public void addColleague(User user) {
    mUsers.put(user.getId(), user);
  }
}

// Colleague Class
public abstract class User
{
  private Mediator mediator;
  private int id;
  private String name;
   
  public User(Mediator room, int i, String nm){
    mediator = room;
    name = nm;
    id = i;
  }
   
  public abstract void send(String msg, int userId);
  public abstract void receive(String msg);

  public Mediator getMediator() {
    return mediator;
  }

  public String getId() {
    return id;
  }

  public String getName() {
    return name;
  }
}

// Concrete Colleagues
public class ChatUser extends User {
     
  public ChatUser(Mediator room, int id, String name) {
    super(room, id, name);
  }

  @Override
  public void send(String msg, int userId) {
    System.out.println(getName() + " :: Sending Message : " + msg);
    getMediator().sendMessage(msg, userId);
  }

  @Override
  public void receive(String msg) {
    System.out.println(getName() + " :: Received Message : " + msg);
  }
}

public class MediatorTest 
{
  public static void main(String[] args) 
  {
    Mediator chatroom = new ChatRoom();
     
    User user1 = new ChatUser(chatroom,1, "AN");
    User user2 = new ChatUser(chatroom,2, "BL");
    User user3 = new ChatUser(chatroom,3, "CS");
     
    chatroom.addColleague(user1);
    chatroom.addColleague(user2);
    chatroom.addColleague(user3);
    chatroom.addColleague(user4);

    user1.send("Hello", 2);
    user2.send("Hey", 1);
  }
}