Mediator
Every chat user holds references to every other user and sends messages directly.
Put the talking rules in one mediator.
Many objects talk to many others in a tangle
The picture from life
Airplanes near an airport do not radio each other to decide who lands first. They all talk to the control tower, and the tower tells each one what to do. Adding another plane changes nothing for the others, because they only know the tower.
The problem
What goes wrong when you do not use it.
Every chat user holds references to every other user and sends messages directly. With ten users that is ninety links, and adding a rule like "mute" means changing all of them.
- calls / uses
- Many objects talk to many others in a tangle
- The rules of the conversation change often
- You want to reuse objects without dragging their neighbours along
The idea
How the pattern fixes it.
Put the talking rules in one mediator. Each participant knows only the mediator and tells it what happened. The mediator decides who else to inform.
- calls / uses
Who is who
- ChatRoom (mediator)
- Keeps the members and delivers messages.
- User (colleague)
- Sends through the room, receives from the room.
Build it in steps
- 1Find the web of direct links.
- 2Create a mediator that knows all participants.
- 3Make participants call the mediator instead of each other.
- 4Put the routing rules in the mediator.
Watch it run
Step through the calls. Tap an arrow to jump to it.
Asha says hi. She talks only to the room.
broadcast(asha, 'hi')The code
Python and Java. Try writing the classes yourself from the diagram first.
class ChatRoom: # the mediator
def __init__(self):
self.members = []
def join(self, user):
self.members.append(user)
user.room = self
def broadcast(self, sender, text):
for member in self.members:
if member is not sender:
member.inbox.append(f"{sender.name}: {text}")
class User:
def __init__(self, name):
self.name = name
self.room = None
self.inbox = []
def say(self, text):
self.room.broadcast(self, text) # talks only to the room
def demo():
room = ChatRoom()
asha, bala, chitra = User("Asha"), User("Bala"), User("Chitra")
for user in (asha, bala, chitra):
room.join(user)
asha.say("hi")
return bala.inbox, chitra.inbox, asha.inboxWhat you gain
- Participants are simple and reusable
- All the rules live in one place
What it costs
- The mediator can become a huge god object
- One more point of failure
You have already met it in
- Air traffic control, chat servers, message brokers
- Java's Timer, or MVC controllers sitting between views and models
- UI dialogs where a form controller enables buttons based on fields
Often mixed up with
Make it stick
Build a smart-home hub: a motion sensor, lights and an alarm only talk to the hub. Add the rule "after midnight motion triggers the alarm" in the hub only.