← Назад к вопросам
Приведи пример использования паттерна Strategy
2.2 Middle🔥 161 комментариев
#ООП и паттерны проектирования
Комментарии (1)
🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Пример реализации паттерна Strategy в C#
Паттерн Strategy (Стратегия) — это поведенческий паттерн проектирования, который определяет семейство алгоритмов, инкапсулирует каждый из них и делает их взаимозаменяемыми. Он позволяет изменять алгоритмы независимо от клиентов, которые их используют.
Ключевые компоненты паттерна:
- Контекст (Context): Класс, который использует стратегию. Он хранит ссылку на объект стратегии и может её заменять.
- Интерфейс стратегии (IStrategy): Общий интерфейс для всех конкретных стратегий.
- Конкретные стратегии (ConcreteStrategy): Классы, реализующие интерфейс стратегии, каждый — свою версию алгоритма.
Практический пример: Система оплаты в интернет-магазине
Рассмотрим реализацию системы обработки платежей, где пользователь может выбрать разные способы оплаты.
1. Определяем интерфейс стратегии
// Интерфейс стратегии
public interface IPaymentStrategy
{
bool ProcessPayment(decimal amount);
string GetPaymentMethodName();
}
2. Реализуем конкретные стратегии
// Конкретная стратегия: Оплата кредитной картой
public class CreditCardPaymentStrategy : IPaymentStrategy
{
private readonly string _cardNumber;
private readonly string _cvv;
public CreditCardPaymentStrategy(string cardNumber, string cvv)
{
_cardNumber = cardNumber;
_cvv = cvv;
}
public bool ProcessPayment(decimal amount)
{
// Логика обработки платежа через кредитную карту
Console.WriteLine($"Обработка платежа {amount} руб. через кредитную карту {_cardNumber[^4..]}");
// Имитация проверки
return !string.IsNullOrEmpty(_cardNumber) && _cardNumber.Length ==706;
}
public string GetPaymentMethodName() => "Кредитная карта";
}
// Конкретная стратегия: Оплата через PayPal
public class PayPalPaymentStrategy : IPaymentStrategy
{
private readonly string _email;
public PayPalPaymentStrategy(string email)
{
_email = email;
}
public bool ProcessPayment(decimal amount)
{
// Логика обработки платежа через PayPal
Console.WriteLine($"Обработка платежа {amount} руб. через PayPal аккаунт {_email}");
// Имитация проверки
return _email.Contains("@");
}
public string GetPaymentMethodName() => "PayPal";
}
// Конкретная стратегия: Оплата криптовалютой
public class CryptoPaymentStrategy : IPaymentStrategy
{
private readonly string _walletAddress;
public CryptoPaymentStrategy(string walletAddress)
{
_walletAddress = walletAddress;
}
public bool ProcessPayment(decimal amount)
{
// Логика обработки платежа криптовалютой
Console.WriteLine($"Обработка платежа {amount} руб. через криптокошелёк {_walletAddress[..10]}...");
// Имитация проверки
return _walletAddress.StartsWith("0x");
}
public string GetPaymentMethodName() => "Криптовалюта";
}
3. Создаём контекст
// Контекст: Заказ в интернет-магазине
public class Order
{
private IPaymentStrategy _paymentStrategy;
public decimal TotalAmount { get; private set; }
public bool IsPaid { get; private set; }
public Order(decimal totalAmount)
{
TotalAmount = totalAmount;
IsPaid = false;
}
// Метод для установки стратегии (можно менять на лету)
public void SetPaymentStrategy(IPaymentStrategy paymentStrategy)
{
_paymentStrategy = paymentStrategy;
Console.WriteLine($"Выбран способ оплаты: {_paymentStrategy.GetPaymentMethodName()}");
}
// Метод выполнения оплаты
public bool ProcessOrderPayment()
{
if (_paymentStrategy == null)
{
Console.WriteLine("Не выбран способ оплаты!");
return false;
}
Console.WriteLine($"\nОбработка заказа на сумму {TotalAmount} руб.");
IsPaid = _paymentStrategy.ProcessPayment(TotalAmount);
if (IsPaid)
{
Console.WriteLine("✅ Платёж успешно обработан!");
}
else
{
Console.WriteLine("❌ Ошибка обработки платежа");
}
return IsPaid;
}
}
4. Использование паттерна Strategy
class Program
{
static void Main(string[] args)
{
// Создаём заказ
var order = new Order(9999.99m);
Console.WriteLine("=== Пример 1: Оплата кредитной картой ===");
order.SetPaymentStrategy(new CreditCardPaymentStrategy("1234567812345678", "123"));
order.ProcessOrderPayment();
Console.WriteLine("\n=== Пример 2: Оплата PayPal ===");
order.SetPaymentStrategy(new PayPalPaymentStrategy("customer@example.com"));
order.ProcessOrderPayment();
Console.WriteLine("\n=== Пример 3: Оплата криптовалютой ===");
order.SetPaymentStrategy(new CryptoPaymentStrategy("0x71C7656EC7ab88b098defB751B7401B5f6d8976F"));
order.ProcessOrderPayment();
Console.WriteLine("\n=== Пример 4: Динамическая смена стратегии ===");
// Пользователь передумал и выбрал другой способ
order.SetPaymentStrategy(new CreditCardPaymentStrategy("8765432187654321", "456"));
order.ProcessOrderPayment();
}
}
Преимущества использования паттерна Strategy
- Принцип открытости/закрытости (OCP): Можно добавлять новые стратегии, не изменяя существующий код контекста.
- Избавление от условных операторов: Заменяет громоздкие
switchилиif-elseконструкции на полиморфизм. - Инкапсуляция алгоритмов: Каждая стратегия изолирована в своём классе.
- Возможность тестирования: Каждую стратегию можно тестировать независимо.
- Динамическая смена поведения: Стратегию можно менять во время выполнения программы.
Типичные сценарии применения в Backend-разработке
- Алгоритмы сортировки и фильтрации данных
- Различные способы аутентификации (JWT, OAuth, API-ключи)
- Форматирование данных (JSON, XML, CSV)
- Стратегии кеширования (MemoryCache, Redis, Database)
- Стратегии логирования (File, Database, Cloud)
- Расчёт доставки разными транспортными компаниями
- Генерация отчётов в разных форматах
Паттерн Strategy особенно полезен в микросервисной архитектуре, где разные сервисы могут требовать различных алгоритмов обработки данных, и необходимо обеспечить гибкость и лёгкость расширения системы.