junior
Что такое паттерн Strategy?
Strategy – паттерн, определяющий семейство алгоритмов, инкапсулирующий каждый и делающий их взаимозаменяемыми. Клиент выбирает алгоритм в runtime.
Аналогия из жизни: Strategy – как навигатор с выбором маршрута. Вы можете ехать “быстрее”, “короче” или “без платных дорог” – алгоритм маршрутизации меняется, а интерфейс навигатора остаётся прежним.
Strategy через интерфейс
// Интерфейс стратегии
interface PricingStrategy {
BigDecimal calculatePrice(BigDecimal basePrice, int quantity);
}
// Конкретные стратегии
class RegularPricing implements PricingStrategy {
public BigDecimal calculatePrice(BigDecimal basePrice, int quantity) {
return basePrice.multiply(BigDecimal.valueOf(quantity));
}
}
class BulkPricing implements PricingStrategy {
public BigDecimal calculatePrice(BigDecimal basePrice, int quantity) {
BigDecimal discount = quantity > 100 ? new BigDecimal("0.8") : new BigDecimal("0.9");
return basePrice.multiply(BigDecimal.valueOf(quantity)).multiply(discount);
}
}
// Контекст, использующий стратегию
class OrderService {
private final PricingStrategy pricingStrategy;
OrderService(PricingStrategy pricingStrategy) { // внедряется через DI
this.pricingStrategy = pricingStrategy;
}
BigDecimal calculateTotal(BigDecimal price, int qty) {
return pricingStrategy.calculatePrice(price, qty);
}
}
С лямбдами (Java 8+) Strategy можно реализовать без отдельных классов:
Пример
Map<String, BiFunction<BigDecimal, Integer, BigDecimal>> strategies = Map.of(
"regular", (price, qty) -> price.multiply(BigDecimal.valueOf(qty)),
"bulk", (price, qty) -> price.multiply(BigDecimal.valueOf(qty))
.multiply(new BigDecimal("0.85"))
);
BigDecimal total = strategies.get("bulk").apply(price, quantity);
Важное
- Strategy = OCP (Open/Closed Principle) на практике
- В Java 8+ простые Strategy заменяются лямбдами (
Comparator,Function) - Spring: стратегии как бины, выбор через
@QualifierилиMap<String, Strategy>
Частые ошибки
- Strategy + if/else для выбора – выбор стратегии через DI/Map, а не через if/else
- Strategy для двух строк кода – лямбда проще отдельного класса
Как используется в 2026
Comparator,Predicate,Function– встроенные Strategy в JDK- Spring:
List<PaymentStrategy>– Spring автоматически собирает все реализации
На собеседовании: покажите связь Strategy с OCP и объясните, когда достаточно лямбды вместо полноценного класса. Частая ошибка – реализовать Strategy, а выбор стратегии сделать через if/else, что сводит весь паттерн на нет.