creational
Strategy
Define a family of algorithms, encapsulate each one, and make them interchangeable.
There are several ways to do the same job. Sort by price, by rating, by distance. Pay by card, wallet or bank transfer.
Written as one long if/else, the method grows every time you add an option. Each change risks breaking the branches that already worked.
Strategy puts each approach in its own class behind a shared interface. The main code holds one of them and calls it. Adding an option means adding a class, not editing the old ones.
GPS navigation — pick fastest route, shortest route, or avoid tolls. The app delegates to whichever strategy you chose.
Key Concepts
1
One interface defines the operation, such as calculate(order).
calculate(order)
2
Each strategy implements it in its own way. The context class holds a reference to the interface and calls it, without knowing which implementation it has.
3
Because the reference can be swapped, the behaviour can change while the program runs.
4
In modern Java, a strategy is often just a lambda or a method reference. Same idea, far less code, and worth mentioning in an interview.
When to use it
- Multiple sorting/searching/compression algorithms
- Payment methods
- Pricing strategies
Watch out for
- The client has to know enough to pick a strategy, so the conditional often moves outward rather than disappearing
- A class per strategy adds up; in modern Java a lambda or method reference is usually the same pattern with none of the boilerplate
- Strategies that need different inputs push you toward a fat shared interface or a parameter object, at which point the abstraction is leaking
java
public interface PaymentStrategy {
void pay(double amount);
}
public class CreditCardPayment implements PaymentStrategy {
private final String card;
public CreditCardPayment(String c) { this.card = c; }
public void pay(double amount) { System.out.println("Card: " + amount); }
}
public class ShoppingCart {
private PaymentStrategy strategy;
public void setPaymentStrategy(PaymentStrategy s) { this.strategy = s; }
public void checkout(double total) { strategy.pay(total); }
}