π― 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?
- Real Life Analogy
- When to Use Strategy Pattern
- Example Problem Statement
- Step by Step Java Implementation
- UML Class Diagram
- Benefits of Strategy Pattern
- Conclusion
β 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
orswitch
). - 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); }
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); } }
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); } }
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); } }
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); } }
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); } }
π§ UML Class Diagram
+---------------------+ | PaymentStrategy |<-- interface +---------------------+ β² +----------+----------+ | | | +------------------+ +----------------+ +------------------+ | CreditCardPayment| | UpiPayment | | PayPalPayment | +------------------+ +----------------+ +------------------+ β² | +------------------+ | PaymentContext | +------------------+ | - strategy | | +setStrategy() | | +payAmount() | +------------------+
π 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
Git: https://github.com/ZeeshanAli-0704/SystemDesignWithZeeshanAli
π Explore More Design Patterns in Java
- π Mastering the Singleton Design Pattern in Java β A Complete Guide
- β οΈ Why You Should Avoid Singleton Pattern in Modern Java Projects
- π Factory Design Pattern in Java β A Complete Guide
- π§° Abstract Factory Design Pattern in Java β Complete Guide with Examples
- π§± Builder Design Pattern in Java β A Complete Guide
- π Observer Design Pattern in Java β Complete Guide
- π Adapter Design Pattern in Java β A Complete Guide
- π Iterator Design Pattern in Java β Complete Guide
- π Decorator Design Pattern in Java β Complete Guide
Top comments (0)