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

Приведи пример цепочки обязанностей

2.0 Middle🔥 62 комментариев
#ООП и паттерны проектирования

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

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

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

Пример паттерна "Цепочка обязанностей" (Chain of Responsibility)

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

Ключевые компоненты паттерна

  1. Handler (обработчик) – абстрактный класс или интерфейс, определяющий метод обработки запроса и ссылку на следующий обработчик.
  2. ConcreteHandler (конкретный обработчик) – реализует логику обработки. Если он может обработать запрос – делает это, иначе передаёт следующему.
  3. Client (клиент) – создаёт цепочку и отправляет запрос первому обработчику.

Практический пример: обработка заказа

Рассмотрим систему обработки заказа, где нужно выполнить проверку доступности товара, проверку баланса пользователя и финальное подтверждение.

1. Определяем абстрактный обработчик

public abstract class OrderHandler
{
    protected OrderHandler? _nextHandler;

    public void SetNext(OrderHandler handler)
    {
        _nextHandler = handler;
    }

    public abstract void Handle(OrderRequest request);
}

2. Создаём конкретные обработчики

Проверка доступности товара:

public class AvailabilityHandler : OrderHandler
{
    public override void Handle(OrderRequest request)
    {
        if (request.ProductAvailable)
        {
            Console.WriteLine("✅ Товар доступен. Передаём следующему обработчику.");
            if (_nextHandler != null)
                _nextHandler.Handle(request);
        }
        else
        {
            Console.WriteLine("❌ Товар недоступен. Обработка прерывается.");
            // Можно добавить логику возврата ошибки
        }
    }
}

Проверка баланса пользователя:

public class BalanceHandler : OrderHandler
{
    public override void Handle(OrderRequest request)
    {
        if (request.UserBalance >= request.OrderPrice)
        {
            Console.WriteLine("✅ Баланс достаточен. Передаём следующему обработчику.");
            if (_nextHandler != null)
                _nextHandler.Handle(request);
        }
        else
        {
            Console.WriteLine("❌ Недостаточно средств. Обработка прерывается.");
        }
    }
}

Финальное подтверждение заказа:

public class ConfirmationHandler : OrderHandler
{
    public override void Handle(OrderRequest request)
    {
        Console.WriteLine($"✅ Заказ на сумму {request.OrderPrice} подтверждён!");
        // Здесь можно добавить логику сохранения заказа в БД
    }
}

3. Класс запроса и клиентский код

public class OrderRequest
{
    public bool ProductAvailable { get; set; }
    public decimal UserBalance { get; set; }
    public decimal OrderPrice { get; set; }
}

public class Client
{
    public void ProcessOrder()
    {
        // Создаём цепочку обработчиков
        var availabilityCheck = new AvailabilityHandler();
        var balanceCheck = new BalanceHandler();
        var confirmation = new ConfirmationHandler();

        availabilityCheck.SetNext(balanceCheck);
        balanceCheck.SetNext(confirmation);

        // Создаём запрос
        var request = new OrderRequest
        {
            ProductAvailable = true,
            UserBalance = 5000,
            OrderPrice = 3000
        };

        // Начинаем обработку с первого звена цепи
        availabilityCheck.Handle(request);
    }
}

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

  • Уменьшает coupling (зависимость) – каждый обработчик независим и знает только о следующем звене.
  • Динамическая конфигурация цепи – можно легко добавлять, удалять или изменять порядок обработчиков.
  • Гибкость – логика обработки распределена между классами, что упрощает поддержку и тестирование.

Типичные сценарии применения в C# Backend

  • Middleware в ASP.NET Core – каждый middleware компонент является звеньем цепи, обрабатывающим HTTP-запрос.
  • Валидация данных – последовательная проверка разных условий (формат, длина, безопасность).
  • Системы логгирования – разные обработчики для записи в файл, отправки в Elasticsearch или уведомления администратора.
  • Обработка исключений – цепочка попыток восстановления (повтор запроса, использование резервного сервиса, запись в журнал).

Использование цепочки обязанностей делает код более модульным и адаптивным к изменениям бизнес-правил, что критически важно для сложных backend-систем.