Low Level Design

Strategy Pattern — Swap Algorithms at Runtime in Java

How the Strategy pattern replaces complex if-else chains with interchangeable algorithm objects, keeping business logic clean and extensible.

August 26, 2026·9 min read

What is the Strategy Pattern?#

The Strategy is a behavioral design pattern that lets you define a family of algorithms, put each into its own class, and make their objects interchangeable at runtime.

The algorithm varies independently from the clients that use it.

You reach for Strategy when:

  • You have multiple ways to perform a task and need to choose at runtime
  • You want to avoid long if-else or switch chains for different behaviors
  • You need to add new algorithms without modifying existing code (OCP)
  • Different classes differ only in their behavior

Real-World Analogy#

Consider Google Maps navigation. You choose a travel strategy:

  • 🚗 Driving — fastest highway route
  • 🚶 Walking — pedestrian paths
  • 🚴 Cycling — bike lanes
  • 🚌 Transit — bus/train routes

The destination stays the same. The strategy to reach it changes based on your selection. The map app doesn't change — only the routing algorithm does.


Class Diagram#


Violation Code — The Problem#

java
class ShoppingCart {
    private String paymentMethod;

    public void setPaymentMethod(String method) {
        this.paymentMethod = method;
    }

    public void checkout(int amount) {
        if (paymentMethod.equals("credit")) {
            System.out.println("Paid $" + amount + " using Credit Card");
        } else if (paymentMethod.equals("paypal")) {
            System.out.println("Paid $" + amount + " using PayPal");
        } else if (paymentMethod.equals("upi")) {
            System.out.println("Paid $" + amount + " using UPI");
        }
        // Adding crypto means touching checkout() again ❌
    }
}

Issues:

  1. Violates OCP — every new payment method requires modifying ShoppingCart
  2. Growing if-else — becomes a maintenance nightmare with many methods
  3. Can't swap at runtime — the method is a string, not a real behavior object
  4. Hard to test — can't substitute mock payment strategies
  5. SRP violation — ShoppingCart knows about all payment implementations

Enhanced Code — Strategy Pattern#

java
// Strategy interface — the contract all algorithms implement
public interface PaymentStrategy {
    void pay(int amount);
}

// Concrete strategies
public class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("Paid $" + amount + " using Credit Card");
    }
}

public class PayPalPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("Paid $" + amount + " using PayPal");
    }
}

public class UPIPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("Paid $" + amount + " using UPI");
    }
}

// Context — uses a strategy, doesn't know which one
public class ShoppingCart {
    private PaymentStrategy strategy;

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

    public void checkout(int amount) {
        strategy.pay(amount); // delegate — no if-else
    }
}

// Client — picks and swaps strategies at runtime
public class Main {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();

        cart.setPaymentStrategy(new PayPalPayment());
        cart.checkout(150);   // Paid $150 using PayPal

        // Switch strategy at runtime ✅
        cart.setPaymentStrategy(new UPIPayment());
        cart.checkout(75);    // Paid $75 using UPI
    }
}

Adding CryptoPayment → one new class. ShoppingCart is never touched.


Common LLD Problems Using Strategy Pattern#

1. Payment Gateway Integration#

  • Strategies: CreditCardPayment, UPIPayment, NetBankingPayment, WalletPayment
  • Context: User selects a payment method dynamically at checkout.

2. Navigation / Map Routing#

  • Strategies: DrivingRoute, WalkingRoute, CyclingRoute, TransitRoute
  • Context: Route calculation changes based on user's transport preference.

3. Sorting Algorithms#

  • Strategies: QuickSort, MergeSort, HeapSort, BubbleSort
  • Context: Algorithm selected dynamically based on data characteristics.

4. Compression Tool#

  • Strategies: ZipCompression, RarCompression, TarCompression
  • Context: Format chosen based on file type or user preference.

5. Discount / Promotion Engine#

  • Strategies: FlatDiscount, PercentageDiscount, BuyOneGetOneFree
  • Context: Applied at checkout based on active promotions.

6. Tax Calculation#

  • Strategies: IndiaTaxStrategy, USATaxStrategy, UKTaxStrategy
  • Context: E-commerce platforms serving multiple markets.

7. Logging Backend#

  • Strategies: ConsoleLogger, FileLogger, DatabaseLogger, CloudLogger
  • Context: Environment-based or runtime-configurable logging destinations.

8. Recommendation Engine#

  • Strategies: CollaborativeFiltering, ContentBasedFiltering, TrendingBased
  • Context: Selectable or combined recommendation backends.

Structure Summary#

RoleResponsibility
Strategy interfaceDeclares the method all algorithms implement
Concrete strategiesEach implements one specific algorithm
ContextHolds a strategy reference; delegates work to it
ClientCreates a strategy and injects it into the context

Strategy vs State#

Both patterns use composition to swap behavior, but:

StrategyState
Who changes?Client swaps algorithmsObject transitions states internally
PurposeInterchangeable algorithmsState-dependent behavior
AwarenessStrategies are independentStates may know about each other

ReferencesLinks
Article ReferenceRefactoring Guru — Strategy