Mediator
Intent
Define an object that encapsulates how a set of objects interact.
Mediator promotes loose coupling by keeping objects from referring
to each other explicitly, and it lets you vary their interaction
independently.
Problem
We want to design reusable components, but dependencies between the
potentially reusable pieces demonstrates the "spaghetti code" phenomenon
(trying to scoop a single serving results in an "all or nothing clump").
Discussion
Partitioning a system into many objects generally enhances reusability,
but proliferating interconnections between those objects tend to reduce
it again. The mediator object: encapsulates all interconnections, acts
as the hub of communication, is responsible for controlling and
coordinating the interactions of its clients, and promotes loose
coupling by keeping objects from referring to each other explicitly.
The Mediator pattern promotes a "many-to-many relationship network" to
"full object status". Modelling the inter-relationships with an object
enhances encapsulation, and allows the behavior of those
inter-relationships to be modified or extended through subclassing.
An example where Mediator is useful is the design of a user and group
capability in an operating system. A group can have zero or more
users, and, a user can be a member of zero or more groups. The
Mediator pattern provides a flexible and non-invasive way to associate
and manage users and groups.
Structure
Example
The Mediator defines an object that controls how a set of objects
interact. Loose coupling between colleague objects is achieved by
having colleagues communicate with the Mediator, rather than with each
other. The control tower at a controlled airport demonstrates this
pattern very well. The pilots of the planes approaching or departing
the terminal area communicate with the tower rather than explicitly
communicating with one another. The constraints on who can take off or
land are enforced by the tower. It is important to note that the tower
does not control the whole flight. It exists only to enforce
constraints in the terminal area. [Michael Duell, "Non-software
examples of software design patterns", Object Magazine,
Jul 97, p54]
Non-software example
Rules of thumb
Chain of Responsibility, Command, Mediator, and Observer, address how
you can decouple senders and receivers, but with different trade-offs.
Chain of Responsibility passes a sender request along a chain of
potential receivers. Command normally specifies a sender-receiver
connection with a subclass. Mediator has senders and receivers
reference each other indirectly. Observer defines a very decoupled
interface that allows for multiple receivers to be configured at
run-time. [GOF, p347]
Mediator and Observer are competing patterns. The difference between
them is that Observer distributes communication by introducing
"observer" and "subject" objects, whereas a Mediator object
encapsulates the communication between other objects. We've found it
easier to make reusable Observers and Subjects than to make reusable
Mediators. [GOF, p346]
On the other hand, Mediator can leverage Observer for dynamically
registering colleagues and communicating with them. [GOF, p282]
Mediator is similar to Facade in that it abstracts functionality of
existing classes. Mediator abstracts/centralizes arbitrary
communication between colleague objects, it routinely "adds value", and
it is known/referenced by the colleague objects (i.e. it defines a
multidirectional protocol). In contrast, Facade defines a simpler
interface to a subsystem, it doesn't add new functionality, and it is
not known by the subsystem classes (i.e. it defines a unidirectional
protocol where it makes requests of the subsystem classes but not vice
versa). [GOF, p193]
C++ Demos | Java Demos | Lab