Open In App

Mediator design pattern

The Mediator design pattern is a behavioral pattern that defines an object, the mediator, to centralize communication between various components or objects in a system. This promotes loose coupling by preventing direct interactions between components, instead of having them communicate through the mediator, facilitating better maintainability and flexibility in the system architecture.

What is the Mediator Design Pattern?

A mediator design pattern is one of the important and widely used behavioral design patterns. Mediator enables the decoupling of objects by introducing a layer in between so that the interaction between objects happens via the layer. Real Life

It defines how a mediator object facilitates the interaction between other objects, guiding their behavior and communication without them being directly aware of each other. This pattern emphasizes the behavior and communication patterns among objects.



Real-Life Analogy of the Mediator Design Pattern

Let’s imagine a group project in a classroom:

Student talks to Teacher, Teacher manages the communication, and the information goes back through the Teacher to the requesting student. This way, everyone collaborates effectively, and individual students don’t have to directly deal with all the details of each other’s work.

Components of the Mediator Design Pattern

1. Mediator

The Mediator interface defines the communication contract, specifying methods that concrete mediators should implement to facilitate interactions among colleagues.. It encapsulates the logic for coordinating and managing the interactions between these objects, promoting loose coupling and centralizing control over their communication.

2. Colleague

Colleague classes are the components or objects that interact with each other. They communicate through the Mediator, and each colleague class is only aware of the mediator, not the other colleagues. This isolation ensures that changes in one colleague do not directly affect others.

3. Concrete Mediator

Concrete Mediator is a specific implementation of the Mediator interface. It coordinates the communication between concrete colleague objects, handling their interactions and ensuring a well-organized collaboration while keeping them decoupled.

4. Concrete colleague

Concrete Colleague classes are the specific implementations of the Colleague interface. They rely on the Mediator to communicate with other colleagues, avoiding direct dependencies and promoting a more flexible and maintainable system architecture.

How components are interacting with each other ?

Below is the communication flow between components:

Mediator Design Pattern example

In an airport, there are multiple airplanes that need to communicate and coordinate their movements to avoid collisions and ensure safe takeoffs and landings. Without a centralized system, direct communication between airplanes could lead to chaos and increased risk.

What can be the challenges while implementing this system?

How Mediator Pattern help to solve above challenges?

The Mediator pattern helps in managing the complex communication and coordination between airplanes and air traffic controllers, ensuring a safer and more organized aviation system. The centralized control provided by the mediator simplifies interactions, reduces the risk of errors, and promotes a scalable and maintainable solution in the aviation domain.

Below is the code of above problem statement using Command Pattern:

1. Colleague Interface(Airplane)




// Colleague Interface
public interface Airplane {
    void requestTakeoff();
    void requestLanding();
    void notifyAirTrafficControl(String message);
}

2. ConcreteColleague Class(CommercialAirplane)




// Concrete Colleague
public class CommercialAirplane implements Airplane {
    private AirTrafficControlTower mediator;
 
    public CommercialAirplane(AirTrafficControlTower mediator) {
        this.mediator = mediator;
    }
 
    @Override
    public void requestTakeoff() {
        mediator.requestTakeoff(this);
    }
 
    @Override
    public void requestLanding() {
        mediator.requestLanding(this);
    }
 
    @Override
    public void notifyAirTrafficControl(String message) {
        System.out.println("Commercial Airplane: " + message);
    }
}

3. Mediator Interface(AirTrafficControlTower)




// Mediator Interface
public interface AirTrafficControlTower {
    void requestTakeoff(Airplane airplane);
    void requestLanding(Airplane airplane);
}

4. ConcreteMediator Class(AirportControlTower)




// Concrete Mediator
public class AirportControlTower implements AirTrafficControlTower {
    @Override
    public void requestTakeoff(Airplane airplane) {
        // Logic for coordinating takeoff
        airplane.notifyAirTrafficControl("Requesting takeoff clearance.");
    }
 
    @Override
    public void requestLanding(Airplane airplane) {
        // Logic for coordinating landing
        airplane.notifyAirTrafficControl("Requesting landing clearance.");
    }
}

Complete code for the above example

Below is the complete code for the above example:




// Colleague Interface
interface Airplane {
    void requestTakeoff();
    void requestLanding();
    void notifyAirTrafficControl(String message);
}
 
// Concrete Colleague
class CommercialAirplane implements Airplane {
    private AirTrafficControlTower mediator;
 
    public CommercialAirplane(AirTrafficControlTower mediator) {
        this.mediator = mediator;
    }
 
    @Override
    public void requestTakeoff() {
        mediator.requestTakeoff(this);
    }
 
    @Override
    public void requestLanding() {
        mediator.requestLanding(this);
    }
 
    @Override
    public void notifyAirTrafficControl(String message) {
        System.out.println("Commercial Airplane: " + message);
    }
}
 
// Mediator Interface
interface AirTrafficControlTower {
    void requestTakeoff(Airplane airplane);
    void requestLanding(Airplane airplane);
}
 
// Concrete Mediator
class AirportControlTower implements AirTrafficControlTower {
    @Override
    public void requestTakeoff(Airplane airplane) {
        // Logic for coordinating takeoff
        airplane.notifyAirTrafficControl("Requesting takeoff clearance.");
    }
 
    @Override
    public void requestLanding(Airplane airplane) {
        // Logic for coordinating landing
        airplane.notifyAirTrafficControl("Requesting landing clearance.");
    }
}
 
// Main class
public class MediatorAirplaneExample {
    public static void main(String[] args) {
        // Instantiate the Mediator (Airport Control Tower)
        AirTrafficControlTower controlTower = new AirportControlTower();
 
        // Instantiate Concrete Colleagues (Commercial Airplanes)
        Airplane airplane1 = new CommercialAirplane(controlTower);
        Airplane airplane2 = new CommercialAirplane(controlTower);
 
        // Set up the association between Concrete Colleagues and the Mediator
        airplane1.requestTakeoff();
        airplane2.requestLanding();
 
        // Output:
        // Commercial Airplane: Requesting takeoff clearance.
        // Commercial Airplane: Requesting landing clearance.
    }
}




Commercial Airplane: Requesting takeoff clearance.
Commercial Airplane: Requesting landing clearance.

When to use the Mediator Design Pattern

When not to use the Mediator Design Pattern


Article Tags :