Understanding Strategy Design Pattern: A Simple Guide



This content originally appeared on DEV Community and was authored by Heli Shah

Design patterns are essential tools in a software engineer’s toolkit. They help solve common problems with proven solutions. Among the behavioral patterns, the Strategy Design Pattern stands out for its flexibility and ability to keep code clean and maintainable. In this blog post, we’ll explore the Strategy Pattern, understand when to use it, and see a practical implementation in Java.

What is the Strategy Pattern?

The Strategy Pattern allows you to define a family of algorithms, encapsulate each one as a separate class, and make them interchangeable. Instead of hardcoding a behavior into a class, the behavior is pulled out and placed into separate strategy classes.

Category: Behavioral Design Pattern
Purpose: Select an algorithm’s behavior at runtime.

When to Use the Strategy Pattern

You should consider using the Strategy Pattern when:

  • You have multiple related algorithms that vary only in behavior.
  • You need to switch algorithms at runtime.
  • You want to avoid multiple conditional statements like if or switch.
  • You want to adhere to the Open/Closed Principle (open for extension, closed for modification).

Real-World Analogy

Think of a navigation app. You can choose between different strategies to reach your destination:

  • Fastest Route
  • Shortest Distance
  • Avoid Tolls

Each of these is a different strategy for solving the same problem: navigation. The app lets you pick the strategy dynamically.

Structure of the Strategy Pattern

  1. Strategy Interface: Common interface for all strategies.
  2. Concrete Strategies: Implement the interface with specific behaviors.
  3. Context: Maintains a reference to the strategy and delegates the behavior.

Java Implementation: Payment System

Let’s implement a payment system where the user can choose how to pay: via Credit Card, PayPal, or UPI.

1. Strategy Interface

public interface PaymentStrategy {
    void pay(double amount);
}

2. Concrete Strategies

public class CreditCardPayment implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("Paid ₹" + amount + " using Credit Card");
    }
}

public class PayPalPayment implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("Paid ₹" + amount + " using PayPal");
    }
}

public class UPIPayment implements PaymentStrategy {
    public void pay(double amount) {
        System.out.println("Paid ₹" + amount + " using UPI");
    }
}

3. Context Class

public class PaymentProcessor {
    private PaymentStrategy strategy;

    public PaymentProcessor(PaymentStrategy strategy) {
        this.strategy = strategy;
    }

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

    public void processPayment(double amount) {
        strategy.pay(amount);
    }
}

4.Usage

public class StrategyPatternDemo {
    public static void main(String[] args) {
        PaymentProcessor processor = new PaymentProcessor(new CreditCardPayment());
        processor.processPayment(2500.00);

        processor.setStrategy(new PayPalPayment());
        processor.processPayment(1200.00);

        processor.setStrategy(new UPIPayment());
        processor.processPayment(500.00);
    }
}

Output:

Paid ₹2500.0 using Credit Card
Paid ₹1200.0 using PayPal
Paid ₹500.0 using UPI

Benefits of Using Strategy Pattern

  • Flexibility: You can change the algorithm at runtime.
  • Clean Code: Avoids long if-else or switch statements.
  • Scalability: Easy to add new strategies without touching existing logic.
  • Testability: Each strategy can be tested independently.

Final Thoughts

The Strategy Pattern is ideal when you need different variations of an algorithm and want to keep your code modular and maintainable. It embraces composition over inheritance and aligns perfectly with SOLID principles.

Understanding and applying the Strategy Pattern in your Java applications can help you write better-designed, more testable, and maintainable code.

Ready to replace those messy if-else blocks with elegant strategies? Happy coding! 🚀


This content originally appeared on DEV Community and was authored by Heli Shah