HuntExams Academy logo
JavaIntermediate#design-patterns

What is the Strategy pattern?

Answer

A behavioral pattern that defines a family of interchangeable algorithms, encapsulated behind a common interface, allowing the algorithm to be selected at runtime without modifying the client code.

Example

interface DiscountStrategy { double apply(double price); }
class BlackFridayDiscount implements DiscountStrategy { public double apply(double p) { return p * 0.5; } }
double finalPrice = strategy.apply(100.0);

Detailed explanation

The Strategy pattern is a behavioral design pattern that defines a family of algorithms, encapsulates each one behind a common interface, and makes them interchangeable. Instead of embedding every variation inside one class, the application delegates a particular operation to a strategy object. It is useful when the same task has several implementations, such as calculating discounts, choosing shipping charges, or applying sorting rules. The algorithm can be selected at runtime without changing the code that invokes it through the interface.

In the discount example, DiscountStrategy is the strategy interface, and its apply(double price) method defines the contract. BlackFridayDiscount is a concrete strategy that returns half the supplied price. A checkout service can act as the context: it stores a DiscountStrategy reference, receives the implementation through its constructor, and calls strategy.apply(price). With BlackFridayDiscount selected, applying the strategy to 100.0 produces 50.0. Under the hood, Java uses dynamic method dispatch to invoke the implementation belonging to the actual strategy object, even though the reference is declared using the interface type.

This separates the checkout workflow from discount calculations and uses composition rather than making subclasses of the checkout service for every discount type. Adding a FestivalDiscount usually requires a new implementation and a change wherever strategies are configured or selected, not a change to the checkout calculation itself. This supports the Open/Closed Principle, but it does not eliminate selection logic: a factory, configuration layer, or caller still chooses the strategy. Runtime selection also does not require a setter; constructor injection can select a strategy when the context is created.

Interviewers typically expect you to identify the interface, concrete strategies, and context, then explain the trade-off. Strategies make algorithms independently testable and reduce repeated conditional logic, but introduce extra abstractions and may be unnecessary for a tiny, stable calculation. In Java, a single-abstract-method strategy interface can also be implemented with a lambda. For production monetary calculations, prefer BigDecimal with an explicit rounding policy rather than the example's double, and ensure every strategy respects the same input and output contract.

Key points to remember

  • Strategy encapsulates interchangeable algorithms behind a shared interface.
  • The context delegates algorithm-specific work to an injected strategy object.
  • Java's dynamic method dispatch invokes the selected implementation.
  • New strategies can extend behaviour without modifying the context's algorithm invocation.
  • Selection logic remains somewhere; strategies organise variation rather than eliminate it.

Common mistakes candidates make

  • Claiming that Strategy removes all conditionals or requires a runtime setter.
  • Putting every algorithm inside the context while leaving the strategy implementations as empty wrappers.
  • Confusing Strategy with State: Strategy represents alternative algorithms, while State represents behaviour associated with an object's current state.

Likely follow-up questions

How is Strategy different from the State pattern?

Both delegate behaviour to interchangeable objects, but their intent differs. Strategy represents alternative ways to perform a task, whereas State represents behaviour tied to an object's lifecycle state and may coordinate transitions.

Can a Java lambda implement a strategy?

Yes, if the strategy interface is a functional interface, you can write DiscountStrategy strategy = price -> price * 0.5;. Named classes are often clearer when strategies need substantial logic, dependencies, or configuration.

How would you test the discount strategies and checkout context?

Test each strategy independently using representative prices, boundary values, and the agreed invalid-input rules. Test the context with a simple stub strategy to verify that it delegates correctly and uses the returned price.

Interview tip: Explain the intent first, map the discount example to its three roles, and finish with one benefit and one trade-off.

Related Interview Questions

1
JavaAdvanced#design-patterns

What is the difference between the Adapter and Decorator patterns?

Open
2
JavaAdvanced#design-patterns#oop

What is the difference between composition and inheritance, and why is 'favor composition over inheritance' recommended?

Open
3
JavaAdvanced#design-patterns

What is the Template Method pattern?

Open