Приведи пример поведенческого паттерна проектирования.

«Приведи пример поведенческого паттерна проектирования.» — вопрос из категории Паттерны, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Паттерн Стратегия (Strategy) — это поведенческий паттерн, который определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Он позволяет изменять алгоритм независимо от клиента, который его использует.

Реализация на Java

  1. Интерфейс стратегии: Определяет общий метод для всех алгоритмов.

    public interface PaymentStrategy {
    void pay(int amount);
    }
  2. Конкретные стратегии: Реализуют различные алгоритмы.

    
    public class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    private String cvv;
    
    public CreditCardPayment(String cardNumber, String cvv) {
        this.cardNumber = cardNumber;
        this.cvv = cvv;
    }
    
    @Override
    public void pay(int amount) {
        System.out.println("Paid " + amount + " using Credit Card (" + cardNumber.substring(12) + ")");
        // Логика взаимодействия с платежным шлюзом для карты
    }
    }

public class PayPalPayment implements PaymentStrategy { private String email;

public PayPalPayment(String email) {
    this.email = email;
}

@Override
public void pay(int amount) {
    System.out.println("Paid " + amount + " using PayPal (" + email + ")");
    // Логика взаимодействия с API PayPal
}

}

public class CryptoPayment implements PaymentStrategy { private String walletAddress;

public CryptoPayment(String walletAddress) {
    this.walletAddress = walletAddress;
}

@Override
public void pay(int amount) {
    System.out.println("Paid " + amount + " using Crypto to address: " + walletAddress.substring(0, 8) + "...");
    // Логика проведения крипто-транзакции
}

}


3.  **Контекст:** Хранит ссылку на стратегию и делегирует ей работу.
```java
public class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    private int totalAmount = 0;

    public void addItem(int price) {
        totalAmount += price;
    }

    // Метод для динамической смены стратегии
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }

    public void checkout() {
        if (paymentStrategy == null) {
            throw new IllegalStateException("Payment strategy not set.");
        }
        paymentStrategy.pay(totalAmount); // Делегирование операции стратегии
        totalAmount = 0; // Очистка корзины после оплаты
    }
}
  1. Использование клиентом:

    public class Client {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.addItem(100);
        cart.addItem(50);
    
        // Выбор и применение разных стратегий
        cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9012-3456", "123"));
        cart.checkout(); // Вывод: Paid 150 using Credit Card (3456)
    
        cart.addItem(75);
        cart.setPaymentStrategy(new PayPalPayment("user@example.com"));
        cart.checkout(); // Вывод: Paid 75 using PayPal (user@example.com)
    
        cart.addItem(200);
        cart.setPaymentStrategy(new CryptoPayment("0xAbCdEf1234567890"));
        cart.checkout(); // Вывод: Paid 200 using Crypto to address: 0xAbCdEf...
    }
    }

Преимущества паттерна Стратегия:

  • Соблюдение OCP (Open/Closed Principle): Легко добавить новую стратегию, не изменяя существующий код контекста.
  • Устранение условных операторов: Заменяет длинные if-else или switch конструкции на полиморфизм.
  • Изоляция логики алгоритма: Каждый алгоритм находится в своем собственном классе, что упрощает тестирование и понимание.