What Problem It Solves
You have a family of interchangeable algorithms. The client should be able to pick one at runtime without modifying the calling code.
Strategy vs State
| Aspect | Strategy | State |
|---|---|---|
| Purpose | Choose an algorithm | Change behavior when state changes |
| Who changes | Client (explicitly picks) | Context (internal state transitions) |
| Number of implementations | Many, stable over problem | Few, transition between them |
| Example | Split strategy (equal, percent) | Vending machine (idle, has-money, dispensing) |
Strategy in LLD Problems
| Problem | Strategy Interface | Strategies |
|---|---|---|
| Splitwise (#5) | SplitStrategy | EqualSplit, PercentSplit, ExactSplit, RatioSplit |
| Parking Lot (#1) | PricingStrategy | HourlyPricing, DailyPricing, WeekendSurcharge, SeasonalPricing |
| Payment (#16) | PaymentMethod | CreditCard, UPI, Wallet, NetBanking |
| Notification (#18) | NotificationChannel | EmailChannel, SMSChannel, PushChannel |
| Cache (#31) | EvictionPolicy | LRUPolicy, LFUPolicy, TTLPolicy |
| Search (#25) | RankingStrategy | RelevanceRanking, DateRanking, PopularityRanking |
How to Present in an Interview
"As you can see, adding a new pricing strategy means one new class implementing PricingStrategy. The ParkingFeeCalculator never changes. The factory registers the new strategy. OCP preserved, testable in isolation."
Implementation
// โโโ EXAMPLE 1 โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// WHAT WE ARE IMPLEMENTING:
// A check-out cart selecting pricing deductions (flat, percentage, or
// seasonal discounts) at checkout.
//
// WHERE THE STRATEGY FITS IN:
// DiscountStrategy is the Strategy interface. FlatDiscount and
// PercentageDiscount represent Concrete Strategies. CheckoutCart is the
// Context.
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
// --- Strategy interface ---
interface PricingStrategy {
double calculatePrice(double basePrice, int hours);
}
// --- Concrete strategies ---
class HourlyPricing implements PricingStrategy {
public double calculatePrice(double basePrice, int hours) {
return basePrice * hours;
}
}
class DailyPricing implements PricingStrategy {
public double calculatePrice(double basePrice, int hours) {
int days = (int) Math.ceil(hours / 24.0);
return basePrice * days * 0.8; // 20% discount
}
}
class WeekendSurchargePricing implements PricingStrategy {
private final double surchargeFactor = 1.5;
public double calculatePrice(double basePrice, int hours) {
return basePrice * hours * surchargeFactor;
}
}
// --- Context (uses strategy) ---
class ParkingFeeCalculator {
private final PricingStrategy strategy;
public ParkingFeeCalculator(PricingStrategy strategy) {
this.strategy = strategy;
}
public double calculate(double basePrice, int hours) {
return strategy.calculatePrice(basePrice, hours);
}
}
public class Main {
public static void main(String[] args) {
// Pick strategy at runtime
ParkingFeeCalculator weekday = new ParkingFeeCalculator(new HourlyPricing());
ParkingFeeCalculator weekend = new ParkingFeeCalculator(new WeekendSurchargePricing());
System.out.println("Weekday 5h: " + weekday.calculate(10, 5)); // 50.0
System.out.println("Weekend 5h: " + weekend.calculate(10, 5)); // 75.0
System.out.println("Daily 30h: " + new ParkingFeeCalculator(new DailyPricing()).calculate(10, 30)); // 240.0
}
}Review
Help Us Improve
How helpful was this walkthrough?
Click a star to rate. We actively use this feedback to refine and update our system design content.
Placeholder
Discussion
Share your thoughts, ask questions, or help others.
Loading comments...