1. The Problem: The "If-Else" Nightmare
Imagine designing a Pricing Engine for a ride-hailing app.
public double calculateFare(double distance, String type) {
if (type.equals("Standard")) return distance * 10;
if (type.equals("Premium")) return distance * 20;
if (type.equals("Shared")) return distance * 5;
// Every new ride type requires changing this code! (Violation of OCP)
return 0;
}
2. The Solution: Strategy Pattern
We define a common interface for all algorithms and let the "Context" (the app) choose which one to use at runtime.
Step 1: The Strategy Interface
public interface PricingStrategy {
double calculate(double distance);
}
Step 2: Concrete Strategies
public class StandardPricing implements PricingStrategy {
public double calculate(double distance) { return distance * 10; }
}
public class PremiumPricing implements PricingStrategy {
public double calculate(double distance) { return distance * 20; }
}
Step 3: The Context (PricingEngine)
public class PricingEngine {
private PricingStrategy strategy;
public void setStrategy(PricingStrategy strategy) {
this.strategy = strategy;
}
public double getFare(double distance) {
return strategy.calculate(distance);
}
}
3. Real-world Intuition: The Multi-Charger
Think of a universal power adapter. The "Subject" is the wall outlet, and the "Strategies" are the different plugs (Type-C, Lightning, Micro-USB). You can switch the plug without changing the outlet.
4. Interview Discussion
- Trade-offs: Strategy adds more classes to the project. Don't use it if you only have 2 constant behaviors.
- Spring Boot Tip: Use a
Map<String, PricingStrategy>injected via Constructor to automatically pick the right strategy based on a key.
Final Takeaway
The Strategy pattern is your #1 weapon against Conditional Bloat.