Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 73 additions & 19 deletions advanced/01_design_patterns/singleton_factory.py
Original file line number Diff line number Diff line change
@@ -1,36 +1,90 @@
# Singleton Pattern
"""
Title: Singleton and Factory Design Pattern Example
Author: Python Design Patterns Contributors
Description:
Demonstrates the Singleton and Factory Method design patterns in Python
with a Logger and Animal creation system.
Date: October 2025
"""

from threading import Lock
from typing import Type, Dict


# =============================================================================
# 1. SINGLETON PATTERN (Thread-safe)
# =============================================================================
class SingletonMeta(type):
"""A thread-safe implementation of Singleton."""
_instance = None
_lock: Lock = Lock()

def __call__(cls, *args, **kwargs):
if not cls._instance:
cls._instance = super().__call__(*args, **kwargs)
with cls._lock:
if cls._instance is None:
cls._instance = super().__call__(*args, **kwargs)
return cls._instance


class Logger(metaclass=SingletonMeta):
def log(self, msg):
"""A simple logger class using Singleton pattern."""
def log(self, msg: str) -> None:
print(f"[LOG]: {msg}")

logger1 = Logger()
logger2 = Logger()
assert logger1 is logger2

# =============================================================================
# 2. FACTORY PATTERN
# =============================================================================
class Animal:
def speak(self):
pass
"""Base Animal class."""
def speak(self) -> str:
raise NotImplementedError("Subclasses must implement 'speak' method.")


class Dog(Animal):
def speak(self):
def speak(self) -> str:
return "Woof!"


class Cat(Animal):
def speak(self):
def speak(self) -> str:
return "Meow!"

def animal_factory(animal_type: str) -> Animal:
if animal_type == "dog":
return Dog()
elif animal_type == "cat":
return Cat()
raise ValueError("Unknown animal type")

pet = animal_factory("dog")
print(pet.speak())
class AnimalFactory:
"""Factory for creating Animal instances dynamically."""
_registry: Dict[str, Type[Animal]] = {}

@classmethod
def register_animal(cls, name: str, animal_cls: Type[Animal]) -> None:
cls._registry[name.lower()] = animal_cls

@classmethod
def create(cls, name: str) -> Animal:
if name.lower() not in cls._registry:
raise ValueError(f"Unknown animal type: {name}")
return cls._registry[name.lower()]()


# Register animals dynamically
AnimalFactory.register_animal("dog", Dog)
AnimalFactory.register_animal("cat", Cat)


# =============================================================================
# 3. DEMONSTRATION
# =============================================================================
if __name__ == "__main__":
logger = Logger()
logger.log("Application started.")

pet_type = "dog"
pet = AnimalFactory.create(pet_type)
logger.log(f"Created a {pet_type} that says: {pet.speak()}")

# Validate Singleton behavior
logger2 = Logger()
assert logger is logger2
logger.log("Verified Singleton: Both logger instances are identical.")

logger.log("Application finished successfully.")
Loading