library
intermediateStrategy Pattern with Functional Interfaces
Replace class-based strategy implementations with lambdas and functional interfaces for cleaner code.
Strategy means the behaviour is a parameter. Since Java 8 the parameter is usually a lambda.
Strategy = GPS navigation modes. The destination (context) stays the same, but you can switch between 'fastest route,' 'shortest route,' or 'avoid tolls' (strategies) without changing the map app.
Key Concepts
1
// the old shape: an interface and a class per strategy
interface Discount { double apply(double amount); }
class TenPercent implements Discount {
public double apply(double a) { return a * 0.9; }
}2
// the same thing today
Discount tenPercent = a -> a * 0.9;
Discount none = a -> a;3
What it replaces: a switch that grows forever.
double price(String tier, double amount) {
switch (tier) {
case "gold": return amount * 0.8;
case "silver": return amount * 0.9;
default: return amount;
}
}4
Every new tier edits this method. A dispatch table does not:
5
static final Map<String, Discount> TIERS = Map.of(
"gold", a -> a * 0.8,
"silver", a -> a * 0.9
);6
double price(String tier, double amount) {
return TIERS.getOrDefault(tier, a -> a).apply(amount);
}7
Adding a tier is adding a map entry — nothing existing is touched, which is what the open/closed
principle asks for.
8
Often you need no interface of your own.
Predicate<T> a test
Function<T, R> a transformation
Comparator<T> an ordering
Supplier<T> a factory
Consumer<T> a side effect
UnaryOperator<T> T to T, like the discount above9
The JDK is full of it.
list.sort(Comparator.comparing(Order::total));
list.stream().filter(o -> o.total() > 100);
map.computeIfAbsent(k, key -> load(key));10
Where a class is still better. A strategy that needs state, several methods, a name in a stack trace, or
its own tests. A lambda has no name, so a failure inside one reports as lambda$price$0.
lambda$price$0
11
And in Spring, injecting a Map<String, Discount> of named beans gives you the dispatch table with the
strategies as testable components.
Map<String, Discount>
12
What the interviewer is probing.1. "How has Java 8 changed the Strategy pattern?" Probing: whether you can connect a pattern
to the language. Stalls: "It has not." Moves up: a strategy with one method is a lambda, so the
class per strategy disappears and a Map of lambdas replaces the switch.
13
2. "How does a dispatch map satisfy the open/closed principle?" Probing: the principle applied
concretely. Stalls: "It is cleaner." Moves up: adding a strategy is adding a map entry; no
existing method is edited, which is what open for extension and closed for modification means.
14
3. "When is a class still better than a lambda?" Probing: the limits. Stalls: "Never."
Moves up: when the strategy needs state, several methods, its own tests, or a name — a lambda
appears in stack traces as lambda$method$0.
15
4. "Which JDK interfaces are strategies you already use?" Probing: recognition. Stalls:
"None." Moves up: Comparator, Predicate, Function and Supplier — every sort, filter and map call
is the pattern.