Какой паттерн проектирования вы считаете наиболее полезным и часто применяете?

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

Ответ

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

Почему он полезен:

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

Пример реализации в Java:

// 1. Общий интерфейс стратегии
public interface PaymentStrategy {
    void pay(double amount);
}

// 2. Конкретные стратегии
public class CreditCardPayment implements PaymentStrategy {
    private String cardNumber;
    public CreditCardPayment(String cardNumber) { this.cardNumber = cardNumber; }
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using Credit Card: " + cardNumber);
    }
}

public class PayPalPayment implements PaymentStrategy {
    private String email;
    public PayPalPayment(String email) { this.email = email; }
    @Override
    public void pay(double amount) {
        System.out.println("Paid " + amount + " using PayPal: " + email);
    }
}

// 3. Контекст, использующий стратегию
public class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    private double totalAmount = 0;

    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }

    public void checkout() {
        if (paymentStrategy == null) {
            throw new IllegalStateException("Payment strategy not set");
        }
        paymentStrategy.pay(totalAmount);
    }
}

// 4. Использование
public class Main {
    public static void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        cart.setPaymentStrategy(new CreditCardPayment("1234-5678-9012-3456"));
        cart.checkout(); // Вызывает оплату через кредитную карту

        cart.setPaymentStrategy(new PayPalPayment("user@example.com"));
        cart.checkout(); // Легко переключились на PayPal
    }
}

Где применяется: Сортировка (разные компараторы), валидация, алгоритмы скидок, выбор способа доставки, форматирование данных.