DEV Community

ZeeshanAli-0704
ZeeshanAli-0704

Posted on • Edited on

Strategy Design Pattern in Java – A Complete Guide

🎯 Strategy Design Pattern in Java β€” Explained with Real-Life Problem and Code

β€œDesign patterns are solutions to recurring problems in software design. Think of them as time-tested blueprints.”

In this post, we’ll demystify the Strategy Design Pattern, walk through a real-world use case, and build a clean Java implementation. If you’re preparing for LLD interviews, learning design patterns, or aiming to write flexible and maintainable code, this one’s for you.


πŸ“˜ Table of Contents


βœ… What is the Strategy Design Pattern?

The Strategy Pattern is a behavioral design pattern that enables you to define a family of algorithms, encapsulate each one, and make them interchangeable. The key idea is to delegate the behavior to different strategy classes instead of hardcoding it.

πŸ” Strategy pattern is all about choosing behavior at runtime.


🧠 Real Life Analogy

Think about a navigation app like Google Maps.

  • You want to go from Point A to Point B.
  • Based on conditions (fastest, least traffic, shortest), the route strategy changes.
  • The app uses a strategy (algorithm) to calculate the best route.

These strategies are:

  • πŸ›£οΈ Fastest Route
  • πŸš— Shortest Distance
  • 🧭 Avoid Tolls

At runtime, the user picks the strategy.


πŸ“Œ When to Use Strategy Pattern

Use the Strategy pattern when:

  • You have multiple algorithms for a specific task.
  • You want to switch between algorithms at runtime.
  • You want to reduce conditionals (if-else or switch).
  • You want to follow the Open/Closed Principle (OCP) – Open for extension, closed for modification.

πŸ’¬ Example Problem Statement

🧾 Design a payment system where a user can pay using different payment methods β€” Credit Card, UPI, and PayPal. The system should allow selecting or switching payment strategy dynamically at runtime.


πŸ› οΈ Step by Step Java Implementation

Let’s implement this in Java using the Strategy Design Pattern.


Step 1: Create the Strategy Interface

public interface PaymentStrategy { void pay(double amount); } 
Enter fullscreen mode Exit fullscreen mode

Step 2: Implement Different Strategies

public class CreditCardPayment implements PaymentStrategy { private String cardNumber; public CreditCardPayment(String cardNumber) { this.cardNumber = cardNumber; } @Override public void pay(double amount) { System.out.println("Paid β‚Ή" + amount + " using Credit Card: " + cardNumber); } } 
Enter fullscreen mode Exit fullscreen mode
public class UpiPayment implements PaymentStrategy { private String upiId; public UpiPayment(String upiId) { this.upiId = upiId; } @Override public void pay(double amount) { System.out.println("Paid β‚Ή" + amount + " using UPI: " + upiId); } } 
Enter fullscreen mode Exit fullscreen mode
public class PayPalPayment implements PaymentStrategy { private String email; public PayPalPayment(String email) { this.email = email; } @Override public void pay(double amount) { System.out.println("Paid β‚Ή" + amount + " using PayPal: " + email); } } 
Enter fullscreen mode Exit fullscreen mode

Step 3: Create the Context Class

public class PaymentContext { private PaymentStrategy strategy; // Allow strategy to be set at runtime public void setPaymentStrategy(PaymentStrategy strategy) { this.strategy = strategy; } public void payAmount(double amount) { if (strategy == null) { throw new IllegalStateException("Payment strategy not set."); } strategy.pay(amount); } } 
Enter fullscreen mode Exit fullscreen mode

Step 4: Use in Main Class

public class StrategyPatternDemo { public static void main(String[] args) { PaymentContext context = new PaymentContext(); // Using Credit Card context.setPaymentStrategy(new CreditCardPayment("1234-5678-9012-3456")); context.payAmount(1500); // Switching to UPI context.setPaymentStrategy(new UpiPayment("zeeshan@upi")); context.payAmount(800); // Switching to PayPal context.setPaymentStrategy(new PayPalPayment("zeeshan@gmail.com")); context.payAmount(2000); } } 
Enter fullscreen mode Exit fullscreen mode

🧭 UML Class Diagram

 +---------------------+ | PaymentStrategy |<-- interface +---------------------+ β–² +----------+----------+ | | | +------------------+ +----------------+ +------------------+ | CreditCardPayment| | UpiPayment | | PayPalPayment | +------------------+ +----------------+ +------------------+ β–² | +------------------+ | PaymentContext | +------------------+ | - strategy | | +setStrategy() | | +payAmount() | +------------------+ 
Enter fullscreen mode Exit fullscreen mode

🌟 Benefits of Strategy Pattern

Benefit Description
βœ… Open/Closed Principle Add new strategies without modifying existing code
βœ… Flexibility Choose behavior at runtime
βœ… Eliminate Conditionals Replaces large if-else/switch blocks
βœ… Reusability Each strategy is a reusable, independent class

⚠️ Common Pitfalls

  • Too many small classes if overused.
  • Wrong abstraction can lead to complexity.
  • Forgetting default/null strategies can cause runtime issues.

βœ… Real-World Use Cases

  • Payment Gateways
  • Sorting Algorithms (e.g., Comparator)
  • Compression (ZIP, RAR, GZIP)
  • Authentication Strategies (OAuth, JWT, LDAP)
  • Route finding in GPS apps

πŸ”š Conclusion

The Strategy Pattern is a powerful way to inject flexibility into your application by decoupling algorithms from the context where they’re used. It's an essential tool in your LLD (Low-Level Design) toolkit, especially for interview prep and scalable production systems.


More Details:

Get all articles related to system design
Hastag: SystemDesignWithZeeshanAli

systemdesignwithzeeshanali

Git: https://github.com/ZeeshanAli-0704/SystemDesignWithZeeshanAli


πŸ“š Explore More Design Patterns in Java


Top comments (0)