Mediator pattern: A guide to decoupling object communication

The Mediator pattern is a behavioral design pattern that allows objects to communicate with each other without direct references. This promotes loose coupling and makes the system more flexible and maintainable.

In the Mediator pattern, there is a central mediator object that acts as a hub for communication between all the other objects. The other objects, known as colleagues, communicate with each other through the mediator.

The mediator object has the following responsibilities:

  • It maintains a list of all the colleagues.

  • It provides methods for colleagues to communicate with each other.

  • It forwards messages from one colleague to another.

  • It may also perform other tasks, such as coordinating the behavior of the colleagues or managing their state.

Benefits of the Mediator pattern

The Mediator pattern offers a number of benefits, including:

  • Reduced coupling: The Mediator pattern decouples the colleagues from each other. This means that the colleagues do not need to know anything about each other's implementations. This makes the system more flexible and easier to maintain.

  • Improved cohesion: The Mediator pattern centralizes the communication logic in the mediator object. This makes the system more cohesive and easier to understand.

  • Reusability: The Mediator pattern can be reused in different contexts. For example, the same mediator object can be used to coordinate the communication between different types of colleagues.

Example of the Mediator pattern

Consider a chat application where multiple users can send messages to each other. We can use the Mediator pattern to decouple the users from each other.

class Mediator {
  private List<User> users = new ArrayList<>();

  public void addUser(User user) {
    users.add(user);
  }

  public void sendMessage(User user, String message) {
    for (User otherUser : users) {
      if (otherUser != user) {
        otherUser.receiveMessage(message);
      }
    }
  }
}

class User {
  private Mediator mediator;

  public User(Mediator mediator) {
    this.mediator = mediator;
  }

  public void sendMessage(String message) {
    mediator.sendMessage(this, message);
  }

  public void receiveMessage(String message) {
    // Handle the message
  }
}

In this example, the Mediator class acts as the central hub for communication between the User objects. The User objects do not need to know anything about each other's implementations. They simply send and receive messages through the Mediator object.

Conclusion

The Mediator pattern is a powerful design pattern that can be used to decouple object communication and improve the flexibility and maintainability of software systems.