tgoop.com/Java_Iibrary/1767
Create:
Last Update:
Last Update:
Стратегия в Java —> уходим от нагромождения if-else
Очень часто, когда начинаем писать код и описывать бизнес-логику, мы обклеиваем методы условными конструкциями.
Со временем, при изменении требований или росте сложности, таких условий становится всё больше.
В итоге код становится трудным для поддержки, его тяжело воспринимать, и он теряет черты объектно-ориентированного подхода.
Стратегия —> это поведенческий шаблон проектирования, позволяющий вынести изменяющееся поведение в отдельные классы и подставлять нужную реализацию во время исполнения программы. То есть вместо длинных if-else мы просто передаём объект с требуемой логикой.
Проблема -> громоздкие if-else
public double calculateDiscount(String customerType, double amount) {
if (customerType.equals("regular")) {
return amount * 0.05;
} else if (customerType.equals("vip")) {
return amount * 0.1;
} else if (customerType.equals("super-vip")) {
return amount * 0.2;
} else {
return 0;
}
}
Такой код:
. трудно читать
. неудобно расширять
. легко сломать при добавлении новых веток
Решение через стратегию:
1. Описываем общий интерфейс:
public interface DiscountStrategy {
double applyDiscount(double amount);
}
2. Создаём реализации под разные типы клиентов:
public class RegularDiscount implements DiscountStrategy {
public double applyDiscount(double amount) {
return amount * 0.05;
}
}
public class VipDiscount implements DiscountStrategy {
public double applyDiscount(double amount) {
return amount * 0.1;
}
}
public class SuperVipDiscount implements DiscountStrategy {
public double applyDiscount(double amount) {
return amount * 0.2;
}
}
3. Контекст, который применяет выбранную стратегию:
public class DiscountService {
private final DiscountStrategy strategy;
public DiscountService(DiscountStrategy strategy) {
this.strategy = strategy;
}
public double getDiscountedPrice(double amount) {
return strategy.applyDiscount(amount);
}
}
4. Подбор реализации во время выполнения:
DiscountStrategy strategy = new VipDiscount();
DiscountService service = new DiscountService(strategy);
double price = service.getDiscountedPrice(1000); // 100.0
Теперь каждая логика скидки инкапсулирована в своём классе. Если появляются новые условия, меняется только реализация конкретной стратегии, а не весь метод.
Даже выбор стратегии можно полностью отвязать от if-логики:
Map<String, DiscountStrategy> strategies = Map.of(
"regular", new RegularDiscount(),
"vip", new VipDiscount(),
"super-vip", new SuperVipDiscount()
);
DiscountStrategy strategy = strategies.getOrDefault(customerType, amount -> 0.0);
double result = strategy.applyDiscount(1000);
Таким образом, мы избавляемся от условных блоков и делаем код чище, гибче и проще в сопровождении.