The Goal

Prevent a tangled web of dependencies by forcing objects to communicate through a central hub.

Think of Air Traffic Control (ATC). If 10 airplanes are nearing an airport, they do not talk directly to each other to coordinate landings (that would be a tangled mess of Many-to-Many dependencies). Instead, every airplane talks to the ATC tower, and the tower dictates the behavior.

  1. The Mediator Interface
public interface AirTrafficControl {
    void requestLandingClearance(Airplane airplane);
}
  1. The Concrete Mediator (The Hub)
public class ATCTower implements AirTrafficControl {
    public void requestLandingClearance(Airplane airplane) {
        System.out.println("Tower to " + airplane.getName() + ": You are cleared to land.");
        // The tower could check other airplanes here before granting clearance
    }
}
  1. The Colleague (The objects that need to communicate)
    1. CRITICAL: The colleague MUST know about the mediator
public abstract class Airplane {
    private String name;
    // CRITICAL: The colleague MUST know about the mediator
    protected AirTrafficControl atc; 

    public Airplane(String name, AirTrafficControl atc) {
        this.name = name;
        this.atc = atc;
    }
    
    public String getName() { return name; }
    
    public void requestLanding() {
        // BEHAVIORAL: Delegating communication to the mediator
        atc.requestLandingClearance(this); 
    }
}

// 4. Concrete Colleagues

public class Boeing747 extends Airplane {
    public Boeing747(String name, AirTrafficControl atc) { super(name, atc); }
}

Why this is Behavioral

  • Look at the Airplane class.
  • Unlike the Facade subsystem, the Airplane must have a reference to the AirTrafficControl mediator.
  • It dictates the runtime behavior of how airplanes interact with the rest of the world. Instead of calling otherAirplane.getOutOFMyWay(), it routes all its behavioral requests through the central hub.