DEV Community

Somenath Mukhopadhyay
Somenath Mukhopadhyay

Posted on

Mediator Design Pattern in Python...

This design pattern 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.

The Mediator interface declares a method used by components to notify the mediator about various events. The Mediator may react to these events and triggers specific components to execute different yet specific tasks.

The Base Component provides the basic functionality of storing a mediator's reference inside the component.

Concrete Components implement various functionality. They don't depend on other components.

Let me explain it to you with an example.

Suppose two students Ridit and Rajdeep take a lot of responsibility in a class. But something bad happens between them, and hence they don't talk to each other. So, here comes the ClassMonitor - as a Mediator between Rajdeep and Ridit - if Ridit does anything that needs Rajdeep to do another task, Ridit notifies the Class Monitor, and then the Class Monitor asks Rajdeep to execute the necessary task.

There are many uses for this design pattern. This design pattern can be found in most of the widget message-passing systems - individual widgets don't pass or communicate with each other - but they communicate through the container window.

For Android engineers - you remember how two fragments talk to each other through the container window.

Here goes the source code for this Design Pattern.

Enjoy.

Happy learning.

from abc import ABC, abstractmethod

class ClassMonitor(ABC):
    """
    The Mediator interface declares a method used by components to notify the
    mediator about various events. The Mediator may react to these notifications
    and pass the execution to other components.
    """
    @abstractmethod
    def notify(self, sender, event):
        pass

class ConcreteClassMonitor(ClassMonitor):
    """
    Concrete Mediators implement cooperative behavior by coordinating several
    components.
    """
    def __init__(self, student1, student2):
        self.student1 = student1
        self.student2 = student2

        # The Concrete Mediator is responsible for setting the relationship
        # between the students.
        self.student1.setMonitor(self)
        self.student2.setMonitor(self)

    def notify(self, sender, event):
        if event == "A":
            print("The class Monitor reacts to event A and triggers Rajdeep to do task C")
            self.student2.do_c()
        elif event == "D":
            print("The class Monitor reacts to event D and triggers Ridit to do Task B and Rajdeep to do Task C")
            self.student1.do_b()
            self.student2.do_c()

class BaseStudent:
    """
    The Base Component provides the basic functionality of storing a mediator's
    instance inside component objects.
    """
    def __init__(self, monitor=None):
        self._monitor = monitor

    def get_monitor(self):
        return self._monitor

    def set_monitor(self, monitor):
        self._monitor = monitor

class Ridit(BaseStudent):
    def do_a(self):
        print("Ridit does A.")
        self._monitor.notify(self, "A")

    def do_b(self):
        print("Ridit does B.")
        self._monitor.notify(self, "B")

class Rajdeep(BaseStudent):
    def do_c(self):
        print("Rajdeep does C.")
        # Note: Rajdeep does not notify the monitor after doing C in this example
        # because the original code didn't have a notification here.
        pass

    def do_d(self):
        print("Rajdeep does D")
        self._monitor.notify(self, "D")

if __name__ == '__main__':
    # The client code.
    ridit = Ridit()
    rajdeep = Rajdeep()
    class_monitor = ConcreteClassMonitor(ridit, rajdeep)

    print("Ma'am asks Ridit to do A")
    ridit.do_a()
    print("-" * 30)

    print("Ma'am asks Rajdeep to do D.")
    rajdeep.do_d()
Enter fullscreen mode Exit fullscreen mode

If we run the above program the output will be like the following:

Ma'am asks Ridit to do A

Ridit does A.

The class Monitor reacts to event A and triggers Rajdeep to do task C

Rajdeep does C.

Ma'am asks Rajdeep to do D.

Rajdeep does D

The class Monitor reacts to event D and triggers Ridit to do Task B and Rajdeep to do Task C

Ridit does B.

Rajdeep does C.

Top comments (0)