What is Mediator pattern?

The Mediator pattern is a behavioral design pattern that promotes loose coupling between objects by encapsulating their communication and coordination within a central mediator object. It allows objects to interact with each other indirectly through the mediator, rather than communicating directly.

The Mediator pattern is useful when a system involves a set of objects that need to communicate and collaborate with each other, but direct communication between them would result in tight coupling and a complex web of dependencies. By introducing a mediator, the objects can communicate through it, reducing direct dependencies and simplifying the interactions.

Key components of the Mediator pattern:

  1. Mediator: The mediator is an interface or an abstract class that defines the communication interface between objects. It encapsulates the logic for coordinating and managing the interactions between objects.
  2. Concrete Mediator: The concrete mediator is a specific implementation of the mediator interface. It maintains references to the participating objects and implements the communication and coordination logic among them.
  3. Colleague: The colleague represents an object that interacts with other objects through the mediator. Colleagues are aware of the mediator and communicate with it to send and receive messages.

Benefits and use cases of the Mediator pattern:

  1. Decoupling of objects: The Mediator pattern decouples objects by promoting indirect communication through a mediator. Objects no longer need to be aware of each other and can communicate through the mediator, reducing dependencies and making the system more maintainable and extensible.
  2. Centralized control: The Mediator pattern provides a central point of control and coordination for the interactions between objects. The mediator encapsulates the communication logic, making it easier to understand, modify, and maintain.
  3. Simplifying object interactions: The Mediator pattern simplifies the interactions between objects by abstracting away the complexities of direct communication. Objects only need to know about the mediator and communicate through it, which simplifies their responsibilities and enhances the clarity of their roles.
  4. Promoting reusability: The Mediator pattern promotes reusability by providing a reusable mediator component that can be shared among different objects or systems. The mediator encapsulates the communication logic, which can be reused in different contexts.
  5. Enhancing maintainability and flexibility: The Mediator pattern enhances the maintainability and flexibility of a system by reducing the dependencies and allowing for easier modifications. Changes in the interaction logic can be made in a centralized mediator, without impacting the participating objects.

Example of the Mediator pattern in Java:

// Mediator interface
public interface ChatMediator {
    void sendMessage(String message, User sender);
    void addUser(User user);
}

// Concrete mediator
public class ChatMediatorImpl implements ChatMediator {
    private List<User> users;

    public ChatMediatorImpl() {
        users = new ArrayList<>();
    }

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

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

// Colleague
public abstract class User {
    protected ChatMediator mediator;
    protected String name;

    public User(ChatMediator mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }

    public abstract void sendMessage(String message);
    public abstract void receiveMessage(String message);
}

// Concrete colleague
public class ChatUser extends User {
    public ChatUser(ChatMediator mediator, String name) {
        super(mediator, name);
    }

    public void sendMessage(String message) {
        System.out.println(name + " sends message: " + message);
        mediator.sendMessage(message, this);
    }

    public void receiveMessage(String message) {
        System.out.println(name + " receives message: " + message);
    }
}

// Usage:
ChatMediator mediator = new ChatMediatorImpl();

User user1 = new ChatUser(mediator, "User 1");
User user2 = new ChatUser(mediator, "User 2");
User user3 = new ChatUser(mediator, "User 3");

mediator.addUser(user1);
mediator.addUser(user2);
mediator.addUser(user3);

user1.sendMessage("Hello everyone!");

In the above example, the Mediator pattern is used to facilitate communication between users in a chat application. The ChatMediator interface defines the communication methods that the mediator must implement.

The ChatMediatorImpl class is the concrete mediator that maintains a list of users and implements the communication logic. When a user sends a message, the mediator forwards the message to all other users except the sender.

The User class is the colleague, representing a user in the chat application. It contains a reference to the mediator and defines the abstract methods for sending and receiving messages.

The ChatUser class is a concrete colleague that extends the User class. It implements the specific behavior for sending and receiving messages.

In the usage example, a chat mediator is created, and users are added to it. When a user sends a message, it is sent to the mediator, which then forwards it to all other users. The users receive the messages through the mediator.

By using the Mediator pattern, the objects (users) can communicate indirectly through the mediator, reducing the dependencies between them and simplifying the interaction logic. The mediator acts as a central point of control and coordination, making the system more maintainable and flexible.

error: Content is protected !!