Mediator is a behavioral design pattern that lets you reduce chaotic dependencies between objects. The pattern restricts direct communications between the objects and forces them to collaborate only via a mediator object.

#Mediator in Python

from __future__ import annotations
from abc import ABC

class Mediator(ABC):
    The Mediator interface declares a method used by components to notify the
    mediator about various events. The Mediator may react to these events and
    pass the execution to other components.

    def notify(self, sender: object, event: str) -> None:

class ConcreteMediator(Mediator):
    def __init__(self, component1: Component1, component2: Component2) -> None:
        self._component1 = component1
        self._component1.mediator = self
        self._component2 = component2
        self._component2.mediator = self

    def notify(self, sender: object, event: str) -> None:
        if event == "A":
            print("Mediator reacts on A and triggers following operations:")
        elif event == "D":
            print("Mediator reacts on D and triggers following operations:")

class BaseComponent:
    The Base Component provides the basic functionality of storing a mediator's
    instance inside component objects.

    def __init__(self, mediator: Mediator = None) -> None:
        self._mediator = mediator

    def mediator(self) -> Mediator:
        return self._mediator

    def mediator(self, mediator: Mediator) -> None:
        self._mediator = mediator

Concrete Components implement various functionality. They don't depend on other
components. They also don't depend on any concrete mediator classes.

class Component1(BaseComponent):
    def do_a(self) -> None:
        print("Component 1 does A.")
        self.mediator.notify(self, "A")

    def do_b(self) -> None:
        print("Component 1 does B.")
        self.mediator.notify(self, "B")

class Component2(BaseComponent):
    def do_c(self) -> None:
        print("Component 2 does C.")
        self.mediator.notify(self, "C")

    def do_d(self) -> None:
        print("Component 2 does D.")
        self.mediator.notify(self, "D")

if __name__ == "__main__":
    # The client code.
    c1 = Component1()
    c2 = Component2()
    mediator = ConcreteMediator(c1, c2)

    print("Client triggers operation A.")

    print("\n", end="")

    print("Client triggers operation D.")


Client triggers operation A.
Component 1 does A.
Mediator reacts on A and triggers following operations:
Component 2 does C.

Client triggers operation D.
Component 2 does D.
Mediator reacts on D and triggers following operations:
Component 1 does B.
Component 2 does C.