← Назад к вопросам

Что такое паттерн Стратегия (Strategy)?

2.0 Middle🔥 111 комментариев
#Архитектура и паттерны

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Паттерн Стратегия (Strategy)

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

Основная идея

Вместо того чтобы реализовать несколько вариантов поведения в одном классе или использовать цепочку условных операторов (if/else), мы создаём семейство классов, каждый из которых представляет отдельную стратегию. Клиент выбирает нужную стратегию во время выполнения программы.

Проблема без паттерна

class PaymentProcessor:
    def process(self, amount: float, payment_type: str) -> bool:
        if payment_type == "credit_card":
            # логика обработки кредитной карты
            print(f"Обработка кредитной карты: {amount}")
            return True
        elif payment_type == "paypal":
            # логика обработки PayPal
            print(f"Обработка PayPal: {amount}")
            return True
        elif payment_type == "bitcoin":
            # логика обработки Bitcoin
            print(f"Обработка Bitcoin: {amount}")
            return True
        return False

Этот код становится нечитаемым и сложным в поддержке при добавлении новых способов оплаты.

Решение с паттерном Strategy

from abc import ABC, abstractmethod

# Стратегия (интерфейс)
class PaymentStrategy(ABC):
    @abstractmethod
    def pay(self, amount: float) -> bool:
        pass

# Конкретные стратегии
class CreditCardPayment(PaymentStrategy):
    def __init__(self, card_number: str, cvv: str):
        self.card_number = card_number
        self.cvv = cvv
    
    def pay(self, amount: float) -> bool:
        print(f"Обработка платежа по карте {self.card_number}: {amount}")
        # Логика валидации и обработки платежа
        return True

class PayPalPayment(PaymentStrategy):
    def __init__(self, email: str):
        self.email = email
    
    def pay(self, amount: float) -> bool:
        print(f"Обработка PayPal платежа ({self.email}): {amount}")
        # Логика обработки через PayPal API
        return True

class BitcoinPayment(PaymentStrategy):
    def __init__(self, wallet_address: str):
        self.wallet_address = wallet_address
    
    def pay(self, amount: float) -> bool:
        print(f"Обработка Bitcoin платежа ({self.wallet_address}): {amount}")
        # Логика обработки блокчейн-платежа
        return True

# Контекст (использует стратегию)
class PaymentProcessor:
    def __init__(self, strategy: PaymentStrategy):
        self.strategy = strategy
    
    def process_payment(self, amount: float) -> bool:
        return self.strategy.pay(amount)
    
    def set_strategy(self, strategy: PaymentStrategy):
        self.strategy = strategy

# Использование
if __name__ == "__main__":
    processor = PaymentProcessor(CreditCardPayment("1234-5678-9012-3456", "123"))
    processor.process_payment(100.0)  # Обработка платежа по карте
    
    # Смена стратегии во время выполнения
    processor.set_strategy(PayPalPayment("user@example.com"))
    processor.process_payment(50.0)   # Обработка PayPal платежа
    
    processor.set_strategy(BitcoinPayment("1A1z7agoat2PbfJapdvW7Q6ZjQxZEUUP7"))
    processor.process_payment(75.0)   # Обработка Bitcoin платежа

Преимущества

  1. Гибкость — легко добавлять новые стратегии без изменения существующего кода
  2. Инкапсуляция — логика каждого алгоритма изолирована в отдельном классе
  3. Динамический выбор — стратегия может быть выбрана во время выполнения программы
  4. Отсутствие условных операторов — избегаем длинных цепочек if/else
  5. Переиспользуемость — стратегии легко использовать в разных контекстах

Недостатки

  1. Усложнение кода — если стратегий мало, паттерн может быть избыточным
  2. Переиспользование памяти — может потребоваться создание нескольких объектов стратегий

Когда использовать

  • Нужно выбирать алгоритм во время выполнения
  • Есть несколько похожих классов, которые отличаются поведением
  • Нужно избежать большого количества условных операторов
  • Алгоритмы должны быть независимыми от клиента