Implementing Design Patterns in Python: Singleton, Factory, and Observer

The patterns are like making a wheel for yourself every time you face a common architectural problem in software development with Python, instead of using it – using exactly what is proven to be best suited for your thinking and reduce errors, and also making it easier to maintain and scale code.

In this article, you will be learning how to implement the three basic design patterns in Python, which are:

  • The Singleton Pattern
  •  The Factory Method Pattern
  •  The Observer Pattern

Most of the time, you are building software with these patterns when developing backend services, automation systems, real-time apps, large-scale applications, or all applications where design is as important as the code itself.

Why Learn Design Patterns in Python?

That said, let’s jump into the patterns but first; let’s understand why they are important.

Benefits of Using Design Patterns:

  • Enforcing clean code architecture
  • Concern separation 
  • Making the code more modular and testable 
  • Enhancing collaboration in team environments 
  • Preparation for technical interviews 

For quite a few, understanding of these patterns makes the difference between a good software engineer and a great one. Hence, this is one of the things most design patterns Python courses teach.

Singleton Pattern in Python

Purpose:

Ensure a class has one instance and provide a global point of access to it.

Use Cases:

  • Logging systems
  • Configuration managers
  • Database connections

Python Implementation:

class Singleton:
    _instance = None
    def __new__(cls):
        if cls._instance is None:
            cls._instance = super(Singleton, cls).__new__(cls)
        return cls._instance

Usage:

logger1 = Singleton()
logger2 = Singleton()
print(logger1 is logger2)  # Output: True
This approach ensures thread-safe, memory-efficient usage.

Pro Tip: Avoid global variables and use the singleton pattern Python implementation for shared resources instead.

2. Factory Method Pattern in Python

Purpose:

Interface for creating classes, but let subclasses or its methods instantiate a class.

Use Cases:

  • Frameworks that support plugins
  • Object creation based on runtime parameters
  • Parsing logic for APIs or file readers

Python Implementation:

class Notification:
    def notify(self):
        pass
class EmailNotification(Notification):
    def notify(self):
        return “Email sent.”
class SMSNotification(Notification):
    def notify(self):
        return “SMS sent.”
class NotificationFactory:
    @staticmethod
    def get_notification(type):
        if type == “email”:
            return EmailNotification()
        elif type == “sms”:
            return SMSNotification()
        else:
            raise ValueError(“Unknown notification type”)

Usage:

notification = NotificationFactory.get_notification(“sms”)
print(notification.notify())  # Output: SMS sent.

This factory method Python pattern helps decouple object creation from business logic, making your code much more testable and extendable.

3. Observer Pattern in Python

Purpose:

Define a one-to-many relationship between objects, meaning that when one object changes state, all dependents are notified.

Use Cases:

  • GUI applications (button click listeners)
  • Notification systems
  • Event-based applications (like messaging or chat apps)

Python Implementation:

class Publisher:
    def __init__(self):
        self.subscribers = []
    def subscribe(self, observer):
        self.subscribers.append(observer)
    def unsubscribe(self, observer):
        self.subscribers.remove(observer)
    def notify_subscribers(self, message):
        for subscriber in self.subscribers:
            subscriber.update(message)
class Subscriber:
    def update(self, message):
        raise NotImplementedError
class EmailSubscriber(Subscriber):
    def update(self, message):
        print(f”Email received: {message}”)
class SMSSubscriber(Subscriber):
    def update(self, message):
        print(f”SMS received: {message}”)

Usage:

pub = Publisher()
email_client = EmailSubscriber()
sms_client = SMSSubscriber()
pub.subscribe(email_client)
pub.subscribe(sms_client)
pub.notify_subscribers(“Design Patterns Released!”)

The observer pattern Python style is excellent when building event-driven systems where changes should ripple through components.

How to Learn These Patterns Effectively

You can speed up your mastery of design patterns in Python by:

Hands-On Projects:

  • Build a logger using the singleton pattern in Python
  • Build a plugin system using the factory method in Python
  • Create a real-time notification app using the observer pattern in Python

Enroll in a Design Patterns Python Course:

  • Udemy: “Beginner’s Python Design Patterns”
  • Coursera: “Python Object-Oriented Programming”
  • Pluralsight: “Python Design Patterns”

These design patterns Python courses help you with real assignments with real-world scenarios.

Best Practices When Using Patterns

PrincipleDescription
Keep it simpleDon’t force a pattern where a simpler solution exists
Combine smartlyYou can use Singleton + Factory, for instance
Avoid overuseToo many patterns = unnecessary complexity
Add commentsMake your pattern usage clear to other devs
Write testsUnit test your implementation logic

Summary Table

PatternCategoryUsed For
SingletonCreationalOne instance of global resources
FactoryCreationalFlexible object creation
ObserverBehavioralReal-time notifications and updates

Conclusion

These design patterns in Python will help you become a better and more organized programmer. Rather they are at all imperative to write professional-grade software, they do germinate as often on technical interviews and system designs.

To recap:

  • Singleton pattern Python, will be useful when you’d need only one shared resource.
  • Factory method Python to abstract and organize complicated object creation.
  • Observer pattern Python should be used when you want real-time, event-driven communication of two components.

Go ahead and use these patterns by working on a mini-project or joining a particular design patterns python course. Your future self—and your team—will find it worth it.

Leave a Reply

Your email address will not be published. Required fields are marked *