Як Strategy допомагає позбутися безлічі умовних операторів?
Патерн Strategy (Стратегія) допомагає позбутися безлічі if-else і switch,
тому що кожен варіант поведінки чи алгоритм виноситься в окремий клас,
а вибір стратегії стає делегованим, а не закодованим усередині методу.
1. Проблема без патерна
Коли потрібно підтримувати різні способи виконання одного завдання, програмісти часто використовують довгі умовні блоки:
class PaymentService {
public void pay(String method, int amount) {
if (method.equals("CARD")) {
System.out.println("Оплата карткою: " + amount);
} else if (method.equals("PAYPAL")) {
System.out.println("Оплата через PayPal: " + amount);
} else if (method.equals("CRYPTO")) {
System.out.println("Оплата криптовалютою: " + amount);
}
}
}Проблеми:
- При додаванні нового способу оплати потрібно змінювати наявний код.
- Клас росте і втрачає читабельність.
- Порушується принцип Open/Closed (код не відкритий для розширення, а для модифікації).
2. Як це робить Strategy
Кожен спосіб оплати перетворюється на окремий клас, що реалізує спільний інтерфейс:
interface PaymentStrategy {
void pay(int amount);
}
class CardPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Оплата карткою: " + amount);
}
}
class PayPalPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Оплата через PayPal: " + amount);
}
}
class CryptoPayment implements PaymentStrategy {
public void pay(int amount) {
System.out.println("Оплата криптою: " + amount);
}
}Контекст просто делегує виконання обраної стратегії:
class PaymentService {
private PaymentStrategy strategy;
public PaymentService(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void pay(int amount) {
strategy.pay(amount);
}
}3. Використання
PaymentService service = new PaymentService(new PayPalPayment());
service.pay(300); // Викликається потрібна стратегія
service = new PaymentService(new CryptoPayment());
service.pay(200); // Поведінка змінюється без ifТепер при додаванні нової стратегії (наприклад, ApplePay):
- не потрібно чіпати старий код;
- просто додати новий клас
ApplePayPaymentі використовувати його.
4. Що саме усувається
Проблема в if-else | Рішення через Strategy |
|---|---|
| Один метод керує всіма алгоритмами | Кожен алгоритм живе у своєму класі |
| Потрібно редагувати старий код | Додаємо новий клас стратегії |
| Код погано читається | Інтерфейс + маленькі незалежні класи |
| Складно тестувати | Кожну стратегію можна тестувати окремо |
| Жорстка зв'язність | Контекст нічого не знає про деталі реалізації |
5. Чому це працює
Контекст викликає метод стратегії через інтерфейс, а отже, йому байдуже, що саме під капотом. Умови більше не потрібні - просто передається потрібний об'єкт:
context.setStrategy(new CryptoPayment());Висновок
Патерн Strategy позбавляє від безлічі умовних операторів, переводячи вибір алгоритму з "розгалужень" в об'єктну структуру.
Підсумок:
Замість
javaif (...) doA(); else if (...) doB();тепер просто
javastrategy.doAlgorithm();
- і кожна стратегія живе окремо, без жодного
if.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.