Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
🤝 Что такое Mediator (Посредник)?
Mediator (Посредник) — это поведенческий паттерн проектирования, который упрощает взаимодействие между множеством объектов, инкапсулируя их коммуникацию в отдельном объекте-посреднике. Основная цель — уменьшить связанность (coupling) между компонентами системы, заменив прямые связи между объектами на взаимодействие через единый централизованный объект.
🎯 Ключевая идея паттерна
Вместо того чтобы объекты напрямую вызывали методы друг друга (создавая плотную сеть зависимостей), они взаимодействуют только с Mediator, который знает, как обработать их запросы и перенаправить соответствующим получателям.
📊 Проблема, которую решает Mediator
Рассмотрим типичный пример: интерфейс пользователя с множеством элементов управления (кнопки, текстовые поля, чекбоксы). Без посредника каждый элемент должен знать о других:
// ❌ ПЛОХО: Прямые связи между компонентами
class Button
{
private TextBox _textBox;
private CheckBox _checkBox;
public void Click()
{
if (_checkBox.IsChecked)
_textBox.Enable();
else
_textBox.Disable();
}
}
✅ Решение с Mediator
// Посредник знает обо всех компонентах и управляет их взаимодействием
interface IMediator
{
void Notify(object sender, string eventCode);
}
class AuthenticationDialog : IMediator
{
private TextBox _loginTextBox;
private CheckBox _rememberMeCheckBox;
private Button _submitButton;
public void Notify(object sender, string eventCode)
{
if (sender == _loginTextBox && eventCode == "TextChanged")
{
_submitButton.Enabled = !string.IsNullOrEmpty(_loginTextBox.Text);
}
else if (sender == _rememberMeCheckBox && eventCode == "CheckedChanged")
{
// Логика для запоминания пользователя
}
}
}
// Компоненты теперь не знают друг о друге
class Button
{
private IMediator _mediator;
public void Click()
{
_mediator.Notify(this, "Click");
}
}
🔑 Основные компоненты паттерна
- Mediator (Посредник) — интерфейс для взаимодействия с компонентами
- ConcreteMediator (Конкретный посредник) — реализует координацию между компонентами
- Colleague (Коллега) — базовый класс компонентов
- ConcreteColleague (Конкретный коллега) — компоненты, которые взаимодействуют через посредника
💡 Преимущества использования Mediator
- Уменьшение связанности: Компоненты становятся независимыми друг от друга
- Централизация управления: Вся логика взаимодействия в одном месте
- Упрощение повторного использования: Компоненты можно использовать в других системах
- Упрощение тестирования: Посредник можно тестировать отдельно
- Гибкость: Легко добавлять новые компоненты без изменения существующих
⚠️ Недостатки паттерна
- Посредник может стать "божественным объектом": Слишком большая ответственность в одном классе
- Усложнение отладки: Все взаимодействия проходят через дополнительный слой
- Создание новой зависимости: Все компоненты зависят от посредника
🏗️ Пример реализации в C# для Backend
// Посредник для обработки заказов
public interface IOrderMediator
{
Task<OrderResult> ProcessOrder(OrderRequest request);
void RegisterHandler(string step, IOrderHandler handler);
}
public class OrderProcessingMediator : IOrderMediator
{
private readonly Dictionary<string, IOrderHandler> _handlers = new();
public void RegisterHandler(string step, IOrderHandler handler)
{
_handlers[step] = handler;
}
public async Task<OrderResult> ProcessOrder(OrderRequest request)
{
var steps = new[] { "validation", "payment", "inventory", "shipping" };
var context = new OrderContext(request);
foreach (var step in steps)
{
if (_handlers.TryGetValue(step, out var handler))
{
var result = await handler.Handle(context);
if (!result.Success)
return new OrderResult { Success = false, Error = result.Error };
}
}
return new OrderResult { Success = true, OrderId = context.OrderId };
}
}
// Базовый обработчик
public interface IOrderHandler
{
Task<HandlerResult> Handle(OrderContext context);
}
// Конкретные обработчики
public class PaymentHandler : IOrderHandler
{
public async Task<HandlerResult> Handle(OrderContext context)
{
// Логика обработки платежа
return HandlerResult.Success();
}
}
🔄 Mediator в современных фреймворках
ASP.NET Core и MediatR
Библиотека MediatR — популярная реализация паттерна Mediator в .NET:
// Команда
public record CreateUserCommand(string Email, string Password) : IRequest<User>;
// Обработчик
public class CreateUserHandler : IRequestHandler<CreateUserCommand, User>
{
public async Task<User> Handle(CreateUserCommand request, CancellationToken cancellationToken)
{
// Логика создания пользователя
return await _userRepository.CreateAsync(request.Email, request.Password);
}
}
// Контроллер
[ApiController]
public class UsersController : ControllerBase
{
private readonly IMediator _mediator;
[HttpPost]
public async Task<IActionResult> CreateUser(CreateUserCommand command)
{
var user = await _mediator.Send(command);
return Ok(user);
}
}
📈 Когда использовать Mediator?
- Сложные взаимодействия между объектами, когда связи становятся запутанными
- Многоуровневые системы, где нужно централизованное управление
- Event-driven архитектуры и системы с обработкой событий
- Микросервисная архитектура для координации между сервисами
- UI/UX приложения с множеством взаимодействующих компонентов
🎯 Заключение
Mediator — мощный паттерн для управления сложными взаимодействиями в системе. В контексте C# Backend разработки он особенно полезен для:
- Организации бизнес-логики через CQRS
- Разделения ответственности между компонентами
- Создания гибких и масштабируемых архитектур
- Реализации pipeline обработки запросов
Правильное применение Mediator делает код чище, тестируемее и поддерживаемее, но требует внимательного подхода к проектированию, чтобы избежать создания "божественного объекта", который знает слишком много о системе.