0
0
LLDsystem_design~7 mins

Singleton pattern in LLD - System Design Guide

Choose your learning style9 modes available
Problem Statement
When multiple parts of a program create their own instances of a class, it can lead to inconsistent states and wasted resources. This causes bugs that are hard to track and inefficient memory usage.
Solution
The Singleton pattern ensures that a class has only one instance throughout the program. It provides a global point of access to that instance, so all parts of the program use the same object, maintaining consistency and saving resources.
Architecture
Client A
Singleton
Instance
Client B

This diagram shows two clients accessing the same Singleton instance, ensuring only one object exists and is shared.

Trade-offs
✓ Pros
Ensures a single shared instance, preventing conflicting states.
Reduces memory usage by avoiding multiple object creations.
Provides a global access point simplifying object management.
✗ Cons
Can introduce hidden dependencies making testing harder.
May cause issues in multithreaded environments if not implemented carefully.
Violates single responsibility principle by controlling instance creation and business logic.
Use when exactly one instance of a class is needed across the entire application, such as configuration managers or logging services.
Avoid when multiple instances are required or in highly concurrent systems without thread-safe implementation.
Real World Examples
Netflix
Uses Singleton for centralized configuration management to ensure consistent settings across distributed services.
Amazon
Applies Singleton pattern in logging frameworks to maintain a single log manager instance.
LinkedIn
Employs Singleton for caching shared resources to optimize memory and access speed.
Code Example
The before code creates separate Logger instances, causing multiple objects. The after code uses __new__ to ensure only one SingletonLogger instance exists, shared by all.
LLD
### Before Singleton (no pattern)
class Logger:
    def __init__(self):
        self.logs = []

logger1 = Logger()
logger2 = Logger()
print(logger1 is logger2)  # False

### After Singleton pattern
class SingletonLogger:
    _instance = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            cls._instance.logs = []
        return cls._instance

logger1 = SingletonLogger()
logger2 = SingletonLogger()
print(logger1 is logger2)  # True
OutputSuccess
Alternatives
Dependency Injection
Instead of a class controlling its own instance, dependencies are provided externally, improving testability.
Use when: Choose when you want better modularity and easier unit testing.
Multiton
Allows a fixed number of instances identified by keys, unlike Singleton which allows only one.
Use when: Choose when you need controlled multiple instances rather than a single one.
Summary
Singleton pattern ensures only one instance of a class exists and provides a global access point to it.
It prevents inconsistent states and reduces resource usage by sharing the same object.
Careful implementation is needed to handle concurrency and testing challenges.