π― 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)