Можешь привести пример реализации паттерна Chain of Responsibility в программном коде?
Ответ от нейросети
sobes.tech AI
Что хотят услышать интервьюеры:
Паттерн Chain of Responsibility позволяет передавать запрос по цепочке обработчиков, пока один из них не возьмёт его на себя. Это удобно, когда заранее неизвестно, какой именно компонент должен обработать запрос. Важно показать, как обработчики связаны между собой и как запрос проходит по цепочке.
Определение:
Chain of Responsibility — это поведенческий паттерн, в котором запрос передаётся от одного обработчика к следующему, пока не будет найден подходящий обработчик или пока цепочка не закончится. Каждый обработчик либо обрабатывает запрос, либо передаёт его дальше.
Пример использования:
using System;
public abstract class Handler
{
protected Handler? Next { get; private set; }
public Handler SetNext(Handler next)
{
Next = next;
return next;
}
public virtual void Handle(string request)
{
if (Next != null)
Next.Handle(request);
}
}
public class AuthHandler : Handler
{
public override void Handle(string request)
{
if (request == "auth")
{
Console.WriteLine("Запрос обработан: авторизация");
return;
}
base.Handle(request);
}
}
public class LoggingHandler : Handler
{
public override void Handle(string request)
{
if (request == "log")
{
Console.WriteLine("Запрос обработан: логирование");
return;
}
base.Handle(request);
}
}
public class DefaultHandler : Handler
{
public override void Handle(string request)
{
Console.WriteLine($"Запрос не распознан: {request}");
}
}
public class Program
{
public static void Main()
{
var auth = new AuthHandler();
var log = new LoggingHandler();
var fallback = new DefaultHandler();
auth.SetNext(log).SetNext(fallback);
auth.Handle("log");
auth.Handle("auth");
auth.Handle("unknown");
}
}
Пояснение кода:
Код строит цепочку из трёх обработчиков: AuthHandler -> LoggingHandler -> DefaultHandler.
Handler— базовый класс с ссылкой на следующий обработчик.- Метод
SetNextсвязывает элементы цепочки и возвращает переданный обработчик, чтобы удобно строить цепочку вызовами подряд. - Каждый наследник переопределяет
Handle:- если запрос подходит, он обрабатывает его сам;
- если не подходит, вызывает
base.Handle(request), передавая запрос дальше.
AuthHandlerобрабатывает строку"auth".LoggingHandlerобрабатывает строку"log".DefaultHandlerсрабатывает как запасной вариант, если никто раньше не обработал запрос.- В
Mainодин и тот же запрос передаётся в начало цепочки, а дальше он проходит по обработчикам до подходящего.
Ключевые моменты:
- Паттерн уменьшает жёсткую связанность между отправителем запроса и его обработчиками.
- Каждый обработчик решает: обработать запрос или передать дальше.
- Цепочка может быть сколь угодно длинной и настраиваться динамически.
- Удобен для валидации, middleware, обработки событий, прав доступа и маршрутизации.
- Важно предусмотреть обработчик по умолчанию или корректное завершение цепочки.