Шаблон проектирования Strategy

Шаблон проектирования Strategy относится к поведенческим паттернам и используется для выбора алгоритма во время исполнения программы динамически. Этот шаблон позволяет изменять поведение объекта путем изменения используемого алгоритма без изменения структуры класса.

Суть стратегии

Основная идея состоит в выделении различных вариантов поведения (алгоритмов) в отдельные классы, называемые стратегиями, и предоставлении возможности объекту выбрать подходящую стратегию во время выполнения программы.

Таким образом, объекты становятся гибкими и легко адаптируемыми к изменениям требований, так как разные реализации одного и того же функционала представлены отдельными классами, между которыми можно переключаться динамически.

Основные элементы паттерна

Паттерн включает три основных компонента:

1. Интерфейс Стратегии (Strategy)

Интерфейс определяет общую сигнатуру метода, который реализует каждый алгоритм.

interface PaymentStrategy {
    public function pay(float $amount): void;
}

2. Конкретная стратегия (ConcreteStrategy)

Это реализация интерфейса PaymentStrategy, представляющая отдельный алгоритм оплаты.

Например, различные способы оплаты:

class CreditCardPayment implements PaymentStrategy {
    private string $cardNumber;
    
    public function __construct(string $cardNumber) {
        $this->cardNumber = $cardNumber;
    }
    
    public function pay(float $amount): void {
        echo "Оплата кредитной картой №$this->cardNumber на сумму $amount.\n";
    }
}

class PayPalPayment implements PaymentStrategy {
    private string $email;
    
    public function __construct(string $email) {
        $this->email = $email;
    }
    
    public function pay(float $amount): void {
        echo "Оплата через PayPal ($this->email) на сумму $amount.\n";
    }
}

3. Контекст (Context)

Контекст хранит ссылку на выбранную стратегию и делегирует ей выполнение соответствующей операции.

class ShoppingCart {
    private PaymentStrategy $paymentStrategy;
    
    public function setPaymentStrategy(PaymentStrategy $strategy): void {
        $this->paymentStrategy = $strategy;
    }
    
    public function checkout(float $totalAmount): void {
        if (!isset($this->paymentStrategy)) {
            throw new Exception("Стратегия платежа не установлена.");
        }
        
        $this->paymentStrategy->pay($totalAmount);
    }
}

Пример использования

Теперь рассмотрим пример полного сценария:

// Создаем корзину покупок
$cart = new ShoppingCart();

// Выбираем способ оплаты кредиткой
$creditCardPayment = new CreditCardPayment('1234-5678-9012');
$cart->setPaymentStrategy($creditCardPayment);

// Оплачиваем покупку
$cart->checkout(100); // Оплата кредитной картой №1234-5678-9012 на сумму 100.

// Меняем способ оплаты на PayPal
$paypalPayment = new PayPalPayment('example@example.com');
$cart->setPaymentStrategy($paypalPayment);

// Повторно оплачиваем покупку другим способом
$cart->checkout(100); // Оплата через PayPal (example@example.com) на сумму 100.

Преимущества использования паттерна Strategy:

  • Гибкость: Возможность менять реализацию конкретного алгоритма во время выполнения программы.
  • Расширяемость: Легко добавлять новые варианты поведения без изменений существующего кода.
  • Улучшение читаемости и сопровождения: Каждая стратегия изолирована и имеет ясное назначение.

Этот паттерн часто применяется там, где необходимо выбирать одну из нескольких альтернативных реализаций одной и той же функциональности, обеспечивая высокую степень абстракции и возможность расширения приложения без переписывания основной логики.

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *