Mixin Design Pattern

Mixin Design Pattern

I want you to introduce the mixin design pattern in this blog post. I will be using Python language since mixins are some kind of multiple inheritance stuff. A mixin class is not intended to exist on its own but it can be inherited by some other class to provide extra functionality.

Using mixins, we can benefit from the elasticity of multiple inheritance and attribute-getting rules in Python. We can write a lot of features, each of them referring to a mixing and we can combine them in a class. Also, we can write a feature only once and use it in different classes.

Here’s in the example below My mail reader class wasn’t doing anything special apart from just reading the email content. I wanted to add a calendar event scheduler feature to my automatic email reader so created a mixin class for this feature and inherited it in a new class. Mixin class is now providing a feature to the email reader class.

class MailReader(object):
    def read_mail(self, suject: str, message: str):
        print("Reading incoming mail with ChatGPT")
        # email reading logic here...


class CalendarEventMixin(object):
    def create_event(self, title: str, description: str, date: str):
        print("Creating calendar event")
        # calendar event creation logic here...
        ...


class AdvancedMailReader(CalendarEventMixin, MailReader):
    def read_mail(self, suject: str, message: str):
        print("Reading incoming mail with ChatGPT")
        # Reading email and creating calendar event logic
        # if there's an event to be created stated in the incoming mails
        ...

Method Resolution Order using Mixins

The most basically, the example below has a diamond inheritance relation:

    Parent
    /   \
   /     \
Left    Right
   \     /
    \   /
    Child

The method resolution order (MRO) is like this:

  1. Child
  2. Left
  3. Right
  4. Parent

We can test it in Python writing classes like these:

class Parent(object):
    def __init__(self):
        super(Parent, self).__init__()
        print("parent")

class Left(Parent):
    def __init__(self):
        super(Left, self).__init__()
        print("left")

class Right(Parent):
    def __init__(self):
        super(Right, self).__init__()
        print("right")

class Child(Left, Right):
    def __init__(self):
        super(Child, self).__init__()
        print("child")

and running Child() will output like this:

parent
right
left
child

So, we can deduce from here that if we aimed to write a class with multiple mixins and one base class, we should consider this order while using mixins:

class Class(Mixin2, Mixin1, BaseClass):

Resources:
Python Object-Oriented Programming
How does Python’s super() work with multiple inheritance?
Mixins and Python