This tutorial describes how to implement factory design pattern in Python.
Factory Design Pattern
Factory design pattern is a creation design pattern as it deals with creation of Objects. Specifically, it solves the problem of choosing/creating one of many implementations of a type for a given input.
In this article, we will see how we can implement a tutorial service factory that chooses one of several implementations based on an input parameter.
Implementing Factory Design Pattern in Python
Before we get to the coding, let's quickly see a UML diagram consisting of all classes that we are going to deal with -
As we can see, there are 3 different implementations of tutorial service based on underlying storage mechanism such as mysql db, google cloud datastore and simple filesystem.
Here is the code structure of our project -
Here is how this generic TutorialService and its three implementations look in terms of Python code -
tutorial_service.py:
from abc import abstractmethod
class TutorialService(object):
def __init__(self):
print('Initializing Abstract TutorialService...')
@staticmethod
def get_type():
"""
Defines unique type of this service.
"""
pass
@abstractmethod
def get_tutorial_by_id(self, tutorial_id):
"""
Gets the tutorial for input tutorial id.
"""
pass
@abstractmethod
def save_tutorial(self, tutorial):
"""
Saves the tutorial in underlying store.
"""
pass
mysql_tutorial_service.py:
from tutorial_service import TutorialService
class MySqlTutorialService(TutorialService):
def __init__(self):
print('Initializing MySQL based TutorialService...')
@staticmethod
def get_type():
return "mysql"
def get_tutorial_by_id(self, tutorial_id):
# logic to get tutorial from MySQL
return "Test Tutorial managed in MySql"
def save_tutorial(self, tutorial):
print("Saved tutorial in MySql")
datastore_tutorial_service.py:
from tutorial_service import TutorialService
class DatastoreTutorialService(TutorialService):
def __init__(self):
print('Initializing Datastore based TutorialService...')
@staticmethod
def get_type():
return "datastore"
def get_tutorial_by_id(self, tutorial_id):
# logic to get tutorial from MySQL
return "Test Tutorial managed in Datastore"
def save_tutorial(self, tutorial):
print("Saved tutorial in Datastore")
filesystem_tutorial_service.py:
from tutorial_service import TutorialService
class FileSystemTutorialService(TutorialService):
def __init__(self):
print('Initializing FileSystem based TutorialService...')
@staticmethod
def get_type():
return "filesystem"
def get_tutorial_by_id(self, tutorial_id):
# logic to get tutorial from MySQL
return "Test Tutorial managed in File System"
def save_tutorial(self, tutorial):
print("Saved tutorial in File System")
And finally this is how our factory file looks like -
factory.py:
from tservices import *
class TutorialServiceFactory:
def __init__(self):
# Get all subclasses of TutorialService
subclasses = TutorialService.__subclasses__()
# Initialize classes object where subclasses will be stored along with type
self.classes = {}
for subclass in subclasses:
# Add type as key and subclass as value in classes object
self.classes[subclass.get_type()] = subclass
def get_tutorial_service(self, type):
# Get class object corresponding to input type
return self.classes[type]
tutorial_service_factory = TutorialServiceFactory()
print(tutorial_service_factory.get_tutorial_service("mysql"))
print(tutorial_service_factory.get_tutorial_service("datastore"))
print(tutorial_service_factory.get_tutorial_service("filesystem"))
Here is the output of running above program -
<class 'tservices.mysql_tutorial_service.MySqlTutorialService'>
<class 'tservices.datastore_tutorial_service.DatastoreTutorialService'>
<class 'tservices.filesystem_tutorial_service.FileSystemTutorialService'>
You can also find complete project on GitHub Repository here.
Thank you for reading through the tutorial. In case of any feedback/questions/concerns, you can communicate same to us through your comments and we shall get back to you as soon as possible.