Back to Design Patterns
Behavioral Pattern

Mediator Pattern

Promote loose coupling by keeping objects from referring to each other explicitly. Route all communication through a central mediator.

The Centralized Hub

The Mediator acts as the Air Traffic Control (ATC) tower. Pilots (colleagues) don't talk to each other to coordinate landings; they talk to the ATC, which manages the runway queue.

This reduces the number of dependencies in a system of $n$ objects from $n(n-1)/2$ connections to just $n$ connections.

Mediator vs Observer

FeatureMediatorObserver
FlowBidirectionalOne-to-Many
LogicCentralized in MediatorDistributed in Observers

Implementation

// Mediator Pattern — Air Traffic Control (ATC)

// ─── Mediator interface ───────────────────────────────────────
interface ATC {
    void register(Aircraft aircraft);
    void requestLanding(Aircraft aircraft);
}

// ─── Concrete Mediator ────────────────────────────────────────
class RunwayController implements ATC {
    private java.util.List<Aircraft> aircraftList = new java.util.ArrayList<>();
    private boolean runwayFree = true;

    public void register(Aircraft a) { aircraftList.add(a); }

    public void requestLanding(Aircraft a) {
        if (runwayFree) {
            System.out.println("[ATC] " + a.getId() + " cleared to land.");
            runwayFree = false;
        } else {
            System.out.println("[ATC] " + a.getId() + " - Denied. Runway busy.");
        }
    }
}

// ─── Colleague ────────────────────────────────────────────────
abstract class Aircraft {
    protected ATC atc;
    protected String id;
    public Aircraft(String id, ATC atc) { this.id = id; this.atc = atc; }
    public String getId() { return id; }
    public abstract void land();
}

class Flight extends Aircraft {
    public Flight(String id, ATC atc) { super(id, atc); }
    public void land() { atc.requestLanding(this); }
}

// ─── Client ───────────────────────────────────────────────────
public class App {
    public static void main(String[] args) {
        ATC tower = new RunwayController();
        Flight ai101 = new Flight("AI-101", tower);
        Flight ek303 = new Flight("EK-303", tower);

        ai101.land(); // Success
        ek303.land(); // Denied
    }
}

When to Use

Complex UI Forms

Where one field's value affects the visibility or options of five other fields.

Decoupling Colleagues

When you want to reuse objects without them carrying dependencies on their "neighbors."

What's Next?

Continue with other Behavioral patterns: