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

Что такое Mediator?

1.8 Middle🔥 221 комментариев
#Dependency Injection и IoC

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

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

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

🤝 Что такое 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");
    }
}

🔑 Основные компоненты паттерна

  1. Mediator (Посредник) — интерфейс для взаимодействия с компонентами
  2. ConcreteMediator (Конкретный посредник) — реализует координацию между компонентами
  3. Colleague (Коллега) — базовый класс компонентов
  4. 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?

  1. Сложные взаимодействия между объектами, когда связи становятся запутанными
  2. Многоуровневые системы, где нужно централизованное управление
  3. Event-driven архитектуры и системы с обработкой событий
  4. Микросервисная архитектура для координации между сервисами
  5. UI/UX приложения с множеством взаимодействующих компонентов

🎯 Заключение

Mediator — мощный паттерн для управления сложными взаимодействиями в системе. В контексте C# Backend разработки он особенно полезен для:

  • Организации бизнес-логики через CQRS
  • Разделения ответственности между компонентами
  • Создания гибких и масштабируемых архитектур
  • Реализации pipeline обработки запросов

Правильное применение Mediator делает код чище, тестируемее и поддерживаемее, но требует внимательного подхода к проектированию, чтобы избежать создания "божественного объекта", который знает слишком много о системе.