Mediator
Replace a tangle of objects talking to each other with one coordinator they all talk through.
Big idea
A Mediator centralises how a group of objects interact. Instead of every component holding references to every other and calling them directly, each one tells the mediator what happened, and the mediator decides who else needs to react. N objects with N × (N−1) connections become N objects each with one.
The problem it solves
A flight search form has a one-way/return toggle, a return-date picker, a passenger counter, a "travelling with infant" checkbox, and a Search button. Rules: the return date is enabled only for return trips; the infant box is enabled only when there's at least one adult; Search is enabled only when the form is complete. If each widget calls the others directly, the toggle knows the date picker and the button; the counter knows the checkbox and the button; and so on. No widget can be reused on another form, and the rules are smeared across five classes.
Think of it like
An airport control tower. Planes don't radio each other to negotiate who lands first — that would be dozens of conversations and a disaster waiting to happen. Each plane talks only to the tower; the tower sees everything and gives each plane its instructions.
Structure
In code
class Component:
def __init__(self, mediator, name):
self.mediator, self.name, self.enabled = mediator, name, True
def changed(self):
self.mediator.changed(self) # "something happened to me"
class TripToggle(Component):
def __init__(self, m):
super().__init__(m, "trip"); self.value = "one-way"
def set(self, v):
self.value = v; self.changed()
class DatePicker(Component):
def __init__(self, m, name):
super().__init__(m, name); self.value = None
def set(self, v):
self.value = v; self.changed()
class Counter(Component):
def __init__(self, m):
super().__init__(m, "adults"); self.value = 0
def set(self, v):
self.value = v; self.changed()
class SearchForm: # the mediator: every rule lives here
def __init__(self):
self.trip = TripToggle(self)
self.depart = DatePicker(self, "depart")
self.ret = DatePicker(self, "return")
self.adults = Counter(self)
self.search_enabled = False
self.changed(None)
def changed(self, component):
self.ret.enabled = self.trip.value == "return"
complete = self.depart.value and self.adults.value > 0 and (
not self.ret.enabled or self.ret.value)
self.search_enabled = bool(complete)
def status(self):
return f"return date {'on ' if self.ret.enabled else 'off'} | search {'ready' if self.search_enabled else 'blocked'}"
form = SearchForm()
print(form.status())
form.depart.set("2026-12-20"); form.adults.set(2)
print(form.status())
form.trip.set("return")
print(form.status())
form.ret.set("2026-12-27")
print(form.status())output
return date off | search blocked
return date off | search ready
return date on | search blocked
return date on | search readyRun and edit it in the app.
DatePicker and Counter are generic widgets — they'd work on any form. Only SearchForm knows this form's rules.
Six components all need to react to each other. Roughly how many direct links does a mediator replace?
Watch it
How to implement it
- Identify a group of classes that are tightly interconnected and hard to reuse.
- Define a mediator interface with a notification method (
changed(sender, event)). - Give each component a reference to the mediator and make it notify instead of calling peers.
- Move all the "when X changes, update Y" rules into the concrete mediator.
When to use it — and when not to
Use it for dialogs and forms, chat rooms (users send to the room, not to each other), workflow coordination between services, or game rooms where many objects interact. Watch for the mediator turning into a god object — if it grows unmanageable, split it by feature, or switch to Observer-style events where components don't need a central brain.
Pros and cons
| Pros | Cons |
|---|---|
| Components become reusable and simple | The mediator can grow into a god object |
| Interaction rules in one place | A single point of failure and of change |
| Fewer, clearer dependencies | Can hide which component affects which |
How it relates
- Facade simplifies a subsystem for outsiders who use it; a mediator coordinates insiders who know it.
- Observer is often how components notify the mediator; the difference is intent — observer broadcasts to anyone, mediator routes deliberately.
- Chain of Responsibility passes requests in a line; a mediator is a hub.
- The Elevator system case study uses a dispatcher as the mediator between floors and cars.
What's the key difference between Mediator and Facade?
Key terms
- Mediator — An object that encapsulates how a set of objects interact.
- Colleague — A component that communicates through the mediator instead of directly with peers.
- God object — A class that accumulates too much responsibility — the main risk for mediators.