Strategy is one of the most practical GoF patterns in Java because it cleanly separates policy variation from the caller.
Define a family of algorithms, encapsulate each one, and make them interchangeable.
What the pattern is trying to do
Define a family of algorithms, encapsulate each one, and make them interchangeable.
What force creates the need
A caller needs one of several policies or algorithms, but conditional logic and branching are making the code rigid.
How the pattern responds
Move each algorithm into its own strategy implementation behind a shared contract.
How the moving parts fit together
A context depends on a strategy interface and delegates the variable part of its behavior to one selected implementation.
Java example in the Order Management domain
package org.javaomnibus.ecommerce.gof.behavioral;
public interface DiscountPolicy {
Money apply(Order order, Money subtotal);
}
public final class LoyaltyDiscountPolicy implements DiscountPolicy {
@Override
public Money apply(Order order, Money subtotal) {
return subtotal.multiply(95).divide(100);
}
}
public final class CheckoutPricingService {
private final DiscountPolicy discountPolicy;
public CheckoutPricingService(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
public Money totalFor(Order order) {
return discountPolicy.apply(order, order.total());
}
}
Step by step
- The pricing service delegates the varying discount logic to a strategy.
- Policies can change without rewriting the caller.
- This is one of the clearest ways to replace conditionals with composition.
- Strategy is about interchangeable algorithms or policies chosen by context.
Where this pattern helps
- When policies or algorithms vary independently from the caller
- When conditionals are growing around pricing, ranking, routing, or validation rules
When a simpler design is better
- When there is only one stable algorithm
- When the variation is really about lifecycle state rather than policy choice
What this pattern costs
- Adds more types and some indirection
- Can become over-engineered if there is not enough true variation
How this fits today
Strategy is one of the most pervasive patterns in modern Java because policy variation appears everywhere from pricing to serialization to integration routing.
Where teams get it wrong
Calling any interface-plus-implementation pair a strategy weakens the idea if no real algorithm or policy variation exists.