Skip to main content
Low-Level Design·Intermediate

Design Patterns for LLD Interviews

The 7 most frequently tested design patterns in LLD interviews with concrete code examples and the exact problems they solve. Know which pattern to reach for and why.

40 min read 7 sections 5 interview questions
SingletonFactoryStrategyObserverDecoratorStateBuilderCommand PatternTemplate MethodSOLID PrinciplesGang of FourOOP Design

How Patterns Appear in Interviews

Interviewers don't ask 'implement the Strategy pattern.' They ask 'design a parking lot' and then evaluate whether you naturally reach for Strategy for pricing, Factory for spot creation, and Singleton for the lot itself. Patterns are the vocabulary — you demonstrate mastery by using them correctly without being prompted.

The 7 Essential LLD Patterns

01

Strategy — Interchangeable Algorithms

Define a family of algorithms, encapsulate each, make them interchangeable. Use: parking lot pricing (hourly vs daily), sorting algorithms, payment methods. Signal: 'we need multiple ways to do X'.

02

Factory / Factory Method — Object Creation

Centralize object creation logic. Use: creating the right Spot subtype (Compact/Standard/Large), creating the right Piece in Chess. Signal: 'create an object based on a type'.

03

Observer — Event Notification

Define a one-to-many dependency. When one object changes state, all dependents are notified automatically. Use: elevator floor panels, stock ticker subscribers. Signal: 'notify multiple listeners when X happens'.

04

Singleton — Single Instance

Ensure a class has exactly one instance with global access. Use: ParkingLot (one lot in the system), configuration manager, logger. Signal: 'there should only be one X'. Be careful — overused, hides dependencies.

05

State — Object Behavior Based on State

Allow an object to alter behavior when internal state changes. Use: Elevator (IDLE/MOVING/DOORS_OPEN), Order (PLACED/CONFIRMED/SHIPPED/DELIVERED), Traffic Light. Signal: 'behavior changes based on current state'.

06

Decorator — Dynamic Behavior Extension

Attach additional responsibilities to objects dynamically. Use: adding encryption to a file writer, adding logging to a data source. Signal: 'wrap an object to add behavior without changing the class'.

07

Builder — Complex Object Construction

Separate the construction of a complex object from its representation. Use: constructing HTTP requests, database queries, complex configuration objects. Signal: 'object needs many optional parameters'.

Design Patterns — Creational, Structural, Behavioral

Rendering diagram...

Patterns in Action — How 5 Patterns Combine in Parking Lot

Rendering diagram...

Strategy Pattern — Parking Lot Pricing

pythonStrategy Pattern
from abc import ABC, abstractmethod
from datetime import datetime

class PricingStrategy(ABC):
    @abstractmethod
    def calculate_fee(self, entry: datetime, exit: datetime, vehicle_type: str) -> float:
        pass

class HourlyPricing(PricingStrategy):
    RATES = {"Motorcycle": 1.0, "Car": 2.0, "Truck": 3.5}

    def calculate_fee(self, entry, exit, vehicle_type):
        hours = max(1, (exit - entry).seconds / 3600)
        return hours * self.RATES.get(vehicle_type, 2.0)

class FlatRatePricing(PricingStrategy):
    def calculate_fee(self, entry, exit, vehicle_type):
        return 15.0  # flat day rate

class PeakHourPricing(PricingStrategy):
    def __init__(self, base: PricingStrategy):
        self.base = base  # Decorator + Strategy combo

    def calculate_fee(self, entry, exit, vehicle_type):
        fee = self.base.calculate_fee(entry, exit, vehicle_type)
        return fee * 1.5 if 8 <= entry.hour <= 18 else fee

# Usage — swap strategies without changing ParkingLot
lot = ParkingLot(pricing_strategy=HourlyPricing())
lot = ParkingLot(pricing_strategy=PeakHourPricing(HourlyPricing()))

Observer Pattern — Elevator Notification

pythonObserver Pattern
from abc import ABC, abstractmethod

class ElevatorObserver(ABC):
    @abstractmethod
    def on_floor_change(self, elevator_id: int, floor: int): pass

    @abstractmethod
    def on_doors_open(self, elevator_id: int, floor: int): pass

class FloorPanel(ElevatorObserver):
    def __init__(self, floor: int):
        self.floor = floor

    def on_floor_change(self, elevator_id, floor):
        if floor == self.floor:
            print(f"Elevator {elevator_id} arrived at floor {self.floor}")

    def on_doors_open(self, elevator_id, floor):
        if floor == self.floor:
            print(f"Doors open on floor {self.floor}")

class Elevator:
    def __init__(self, id: int):
        self.id = id
        self._floor = 0
        self._observers: list[ElevatorObserver] = []

    def add_observer(self, obs: ElevatorObserver):
        self._observers.append(obs)

    def move_to(self, floor: int):
        self._floor = floor
        for obs in self._observers:
            obs.on_floor_change(self.id, floor)

Pattern Quick Reference

PatternProblem SolvedLLD Problem Example
SingletonSingle shared instanceParkingLot, Logger, Config
FactoryCreate objects by typeParkingSpot, ChessPiece, Vehicle
StrategySwap algorithms at runtimePricing, Dispatch, Sorting
ObserverNotify multiple dependentsElevator panels, Event systems
StateBehavior changes with stateElevator, Order, Traffic Light
DecoratorAdd behavior without subclassingLogging, Encryption wrappers
BuilderConstruct complex objectsHTTP Request, Query Builder

Interview Questions

Click to reveal answers
Test your knowledge

Sign in to take the Quiz

This topic has 17 quiz questions with instant feedback and detailed explanations. Sign in to unlock quizzes.

Sign in to take quiz →