Mediator Pattern

Sean Bradley
Design Patterns In Python
4 min readAug 17, 2020

--

Objects communicate through the Mediator rather than directly with each other.

As a system evolves and becomes larger and supports more complex functionality and business rules, the problem of communicating between these components becomes more complicated to understand and manage. It may be beneficial to refactor your system to centralize some or all of its functionality via some kind of mediation process.

The mediator pattern is similar to creating a Facade pattern between your classes and processes. Except the Mediator is expected to transact data both ways between two or more other classes or processes that would normally interact directly with each other.

The resulting Mediator interface will be very custom to the use cases that it is now supporting.

The Mediator will generally look like an object that is managing one of more Observer patterns perhaps between the other classes or processes (colleagues). Whether you use an Observer pattern to manage a particular piece of functionality or not depends on whether it is the best use of the resources you have available.

When refactoring your code, you may decide to approach your refactoring from the perspective of implementing an Observer pattern first. This means that all colleagues (Observers) will receive the notification whether it was intended for them or not. If you want to avoid redundant updates in the colleagues then you can write specific cases in your code, or create specific methods as I have done in mediator_concept.py example below.

Colleagues now will send and receive requests via a Mediator object rather than directly between each other. The Mediator is like a router in this case, but allows you to add extra programmatic functionality and also give the option of creating other kinds of colleagues that could utilize the communications in new ways.

Terminology

  • Mediator Interface: An interface that the Mediator and Colleagues implement. Note that different Colleagues will have varied use cases and won’t need to implement all the methods described in the Mediator interface.
  • Concrete Mediator: The single source of truth and coordinator of communications between the components (colleagues).
  • Colleague Classes: One of the many types of concrete components that use the mediator for its own particular use case.

Mediator Pattern UML Diagram

Mediator Pattern UML Diagram

Source Code

In the example concept, there are two colleague classes that use each other’s methods. Instead of the Colleagues calling each other’s methods directly, they implement the Mediator interface and call each other via the Mediator. Each colleague class or process is designed for a different purpose, but they utilize some related functionality from each other.

The system would work without the Mediator, but adding the Mediator will allow extending functionality to a potential third colleague that provides a different service, such as AI analysis or monitoring, without needing to add specific support or knowledge into the two original colleagues.

./mediator/mediator_concept.py

"""
Mediator Concept Sample Code
https://sbcode.net/python/mediator/#mediatormediator_conceptpy
"""
from abc import ABCMeta, abstractmethodclass IMediator(metaclass=ABCMeta):
"The Mediator interface indicating all the methods to implement"
@staticmethod
@abstractmethod
def colleague1_method():
"A method to implement"
@staticmethod
@abstractmethod
def colleague2_method():
"A method to implement"
class Mediator(IMediator):
"The Mediator Concrete Class"
def __init__(self):
self.colleague1 = Colleague1()
self.colleague2 = Colleague2()
def colleague1_method(self):
return self.colleague1.colleague1_method()
def colleague2_method(self):
return self.colleague2.colleague2_method()
class Colleague1(IMediator):
"This Colleague calls the other Colleague via the Mediator"
def colleague1_method(self):
return "Here is the Colleague1 specific data you asked for"
def colleague2_method(self):
"not implemented"
class Colleague2(IMediator):
"This Colleague calls the other Colleague via the Mediator"
def colleague1_method(self):
"not implemented"
def colleague2_method(self):
return "Here is the Colleague2 specific data you asked for"
# This Client is either Colleague1 or Colleague2
# This Colleague will instantiate a Mediator, rather than calling
# the other Colleague directly.
MEDIATOR = Mediator()
# If I am Colleague1, I want some data from Colleague2
DATA = MEDIATOR.colleague2_method()
print(f"COLLEAGUE1 <--> {DATA}")
# If I am Colleague2, I want some data from Colleague1
DATA = MEDIATOR.colleague1_method()
print(f"COLLEAGUE2 <--> {DATA}")

Output

python ./mediator/mediator_concept.py    
COLLEAGUE1 <--> Here is the Colleague2 specific data you asked for
COLLEAGUE2 <--> Here is the Colleague1 specific data you asked for

Video of the Mediator Pattern

Example Use Case

Visit Mediator — Design Patterns In Python (sbcode.net) for a use case example of the Mediator pattern.

The use case example is a simplified game engine. There is the main game engine component, a scheduler that manages game events and there are game clients that act as separate game players submitting bets into a game round.

All of the components implement the Mediators interface. They all implement one or some of the methods differently depending on their purpose. While they all perform different types of functionality, they all require a single source of truth being the Game Engine that acts as the Mediator.

Summary

  • A mediator replaces a structure with many-to-many interactions between its classes and processes, with a one-to-many centralized structure where the interface supports all of the methods of the many-to-many structure, but via the mediator component instead.
  • The mediator pattern encourages usage of shared objects that can now be centrally managed and synchronized.
  • The mediator pattern creates an abstraction between two or more components that then makes a system easier to understand and manage.
  • The mediator pattern is similar to the Facade pattern, except the Mediator is expected to transact data both ways between two or more other classes or processes that would normally interact directly with each other.

Video of a Mediator Pattern use case

Thankyou for reading my quick tutorial on the Mediator Design Pattern. For more design patterns please visit my series on Design Patterns in Python at https://medium.com/design-patterns-in-python

Sean

Design Patterns In Python (Book)

You can also buy this series in paperback.
Book provides FREE access to online instructional videos.
Design Patterns In Python : ASIN B08XLJ8Z2J

--

--

Sean Bradley
Design Patterns In Python

Developer of real time, low latency, high availability, asynchronous, multi threaded, remotely managed, fully automated and monitored solutions.