Singleton Design Pattern in Python
What is it?
If you have taken the Python 101 course, you must be familiar with global variables. Global variables are declared using the global keyword, and can be accessed from any point in the program. Such variables are shared i.e. only one copy of these variables is maintained in the memory. The Singleton Design Pattern, is the object oriented equivalent of providing global variables. This is achieved by enabling the class to be instantiated once and only once i.e. only one object can be made of the class.
It is classified under Creational Design Patterns, since it addresses instantiation of classes.
Why the need for it: Problem Statement
The need for Singleton Pattern is felt in a couple of prominent situations, listed below:
- When logging needs to be implemented: The logger instance is shared by all the components of the system to log the messages.
- When a cache of information needs to be maintained for the purpose of being shared by various components in the system: By keeping the information in the shared object, there is no need to fetch the information from its original source every single time. An example of this scenario is configuration files.
- Managing a connection to a database.
Basically, the Singleton Pattern is needed when you need to manage a shared resource. The system needs to have a single instance of the concerned Singleton class in order to avoid conflicting request for the same resource.
How to implement it
# Let's create a class that maintains a shared data dictionary. This dictionary takes key-value pairs from each instance of the class and adds them to itself. class DatabaseConfiguration(): _sharedData = {} def __init__(self, **kwargs): self._sharedData.update(kwargs) # update _sharedData dictionary with key-value pair(s) provided def __str__(self): return str(self._sharedData) # return the _sharedData dictionary when object is printed # Let's add a configuration detail in the form of a key-value pair to the sharedData dictionary configDetailsOne = DatabaseConfiguration(database = "10.10.10.10") # Printing the sharedData dictionary print(configDetailsOne) # OUTPUT: {'database': '10.10.10.10'} # Let's add a few more other configuration details to the sharedData dictionary configDetailsTwo = DatabaseConfiguration(user = "userOne") configDetailsThree = DatabaseConfiguration(password="userOne") configDetailsFour = DatabaseConfiguration(serviceName="serviceOne") # Let's take a look at what the sharedData dictionary now looks like. print(configDetailsFour) # OUTPUT: {'password': 'userOne', 'database': '10.10.10.10', 'user': 'userOne', 'serviceName': 'serviceOne'}
- Creational Patterns
- Factory
- Abstract Factory
- Prototype
- Singleton
- Builder
- Architectural Pattern
- Model View Controller (MVC)