0
0
LLDsystem_design~7 mins

When to use which creational pattern in LLD - System Design Guide

Choose your learning style9 modes available
Problem Statement
Creating objects directly in code can lead to rigid designs that are hard to change or extend. Without a clear approach, adding new types or changing creation logic often requires modifying many parts of the code, increasing bugs and slowing development.
Solution
Creational patterns provide structured ways to create objects, separating the creation logic from usage. Each pattern fits different needs: some create one instance, others create families of related objects, and some allow flexible object creation without specifying exact classes upfront.
Architecture
Client Code
Creator
ConcreteProdA

This diagram shows client code requesting objects from a creator interface, which then instantiates concrete product classes. It illustrates the Factory Method pattern where creation is delegated.

Trade-offs
✓ Pros
Improves code flexibility by decoupling object creation from usage.
Makes it easier to introduce new types without changing existing code.
Supports single instance control (Singleton) or complex object construction (Builder).
Enhances testability by allowing mock or stub objects creation.
✗ Cons
Adds extra layers of abstraction, which can increase code complexity.
May introduce more classes and interfaces, making the codebase larger.
Choosing the wrong pattern can lead to over-engineering or insufficient flexibility.
Use creational patterns when object creation is complex, needs to be controlled, or when the system must support multiple types or configurations of objects. For example, when you want to avoid tight coupling between client code and concrete classes or when you need to manage object lifecycle carefully.
Avoid using creational patterns for simple object creation where direct instantiation is clear and sufficient, especially when the system has low complexity or when performance is critical and the overhead of abstraction is not justified.
Real World Examples
Netflix
Uses the Builder pattern to construct complex streaming session objects with many optional parameters, improving code clarity and flexibility.
Uber
Applies the Factory Method pattern to create different types of ride requests (e.g., UberX, UberPool) without changing client code.
Amazon
Employs the Singleton pattern for managing shared resources like configuration settings and database connection pools.
Code Example
The before code creates a Car object directly, which ties client code to a specific class. The after code uses a factory method to create car objects, allowing easy extension to new car types without changing client code.
LLD
### Before: Direct instantiation (tight coupling)
class Car:
    def __init__(self, model):
        self.model = model

car = Car('Sedan')

### After: Using Factory Method pattern
from abc import ABC, abstractmethod

class Car(ABC):
    @abstractmethod
    def drive(self):
        pass

class Sedan(Car):
    def drive(self):
        print('Driving a sedan')

class Suv(Car):
    def drive(self):
        print('Driving an SUV')

class CarFactory:
    @staticmethod
    def create_car(car_type):
        if car_type == 'sedan':
            return Sedan()
        elif car_type == 'suv':
            return Suv()
        else:
            raise ValueError('Unknown car type')

car = CarFactory.create_car('sedan')
car.drive()
OutputSuccess
Alternatives
Prototype
Creates new objects by cloning existing instances rather than building from scratch.
Use when: When object creation is expensive and you want to copy existing objects with some modifications.
Abstract Factory
Provides an interface to create families of related objects without specifying their concrete classes.
Use when: When you need to create multiple related objects that must be used together and want to ensure compatibility.
Builder
Separates the construction of a complex object from its representation, allowing step-by-step creation.
Use when: When an object requires many steps or configurations to be created and you want to isolate that complexity.
Summary
Creational patterns help manage complex object creation and improve code flexibility.
Each pattern fits different scenarios, such as single instance control, family creation, or stepwise construction.
Choosing the right pattern depends on system complexity, object relationships, and future extensibility needs.