Low-Level Design Tutorial 0/42 lessons ~6 min read Lesson 24

    Strategy Pattern

    The Strategy pattern defines a family of algorithms, encapsulates each, and makes them interchangeable.

    Course progress0%
    Focus
    9 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    The Strategy pattern defines a family of algorithms, encapsulates each, and makes them interchangeable. Elevator scheduling (FCFS vs SCAN), pricing rules, and payment routing are classic LLD examples.

    Strategy is polymorphism applied to behavior variation — client holds Strategy interface and delegates without conditionals. Interview extensions often ask for new strategy without changing client code.

    Inject strategy via constructor for testability.

    Understanding the topic

    Key concepts

    • Strategy interface declares algorithm method.
    • Concrete strategies implement different algorithms.
    • Context class delegates to strategy instance.
    • Runtime strategy swap possible if requirements allow.
    • Eliminates growing switch statements.
    • Related to OCP and DIP directly.
    text
    flowchart LR
    Subject -->|notify| ObserverA
    Subject -->|notify| ObserverB

    Step-by-step explanation

    1. Identify varying algorithm (fare, scheduling, compression).
    2. Extract Strategy interface with compute method.
    3. Implement one class per algorithm.
    4. Context stores Strategy field set at construction.
    5. Client calls context method; context delegates.
    6. Add strategies by new classes only.

    Informative example

    Elevator dispatch strategies:

    java
    public interface DispatchStrategy {
    int selectElevator(List<Elevator> elevators, int requestedFloor);
    }
    public final class NearestCarStrategy implements DispatchStrategy {
    @Override
    public int selectElevator(List<Elevator> elevators, int requestedFloor) {
    return elevators.stream()
    .min(Comparator.comparingInt(e -> Math.abs(e.currentFloor() - requestedFloor)))
    .orElseThrow()
    .id();
    }
    }
    public final class ElevatorController {
    private final List<Elevator> elevators;
    private final DispatchStrategy strategy;
    public ElevatorController(List<Elevator> elevators, DispatchStrategy strategy) {
    this.elevators = elevators;
    this.strategy = strategy;
    }
    public void requestFloor(int floor) {
    int id = strategy.selectElevator(elevators, floor);
    elevators.stream().filter(e -> e.id() == id).findFirst().orElseThrow().addRequest(floor);
    }
    }

    Swap NearestCarStrategy for LoadBalancedStrategy in tests — controller unchanged.

    Real-world use

    Real-world applications

    • Pricing, tax, routing, sorting policies.
    • Compression or validation rules.
    • Game AI difficulty levels.

    Best practices

    • Keep strategies stateless when possible.
    • Name strategies after algorithm (SCAN, FIFO).
    • Inject strategy — avoid hard-coded new in methods.
    • Unit test each strategy independently.
    • Document strategy selection criteria.

    Common mistakes

    • Strategy with hidden context mutation.
    • One strategy class with mode flag (inside switch).
    • Context knowing all concrete strategy types.
    • Over-strategizing trivial one-line differences.

    Advanced interview questions

    Q1BeginnerWhat is Strategy pattern?
    Encapsulate interchangeable algorithms behind common interface.
    Q2BeginnerStrategy vs if-else?
    Strategy scales extension; if-else edits central code for each variant.
    Q3IntermediateWhere does strategy get chosen?
    Composition root, config, or factory — not scattered new statements.
    Q4IntermediateStrategy vs State pattern?
    Strategy often selected externally; State transitions triggered internally by object.
    Q5AdvancedAdd surge pricing to cab booking.
    SurgePricingStrategy implements FareStrategy; TripCalculator holds strategy injected by SurgeService based on demand.

    Summary

    Strategy encapsulates swappable algorithms. Removes conditional logic from clients. Supports OCP for new algorithms. Inject via constructor in Java LLD. Ideal for pricing, dispatch, and routing.

    Ready to mark this lesson complete?Track your journey across the entire course.