Ответ
Медиатор (Mediator) — это поведенческий паттерн проектирования, который уменьшает прямые связи между множеством объектов, заставляя их взаимодействовать не напрямую, а через специальный объект-посредник. Этот посредник централизует сложную логику взаимодействия, делая систему более управляемой и упрощая изменение отдельных компонентов.
Проблема, которую он решает: Представьте группу компонентов UI (кнопки, поля ввода, чекбоксы), которые должны влиять друг на друга. Прямые ссылки между ними создают «паутину зависимостей», где изменение одного компонента влечёт за собой правки в нескольких других. Это делает код хрупким и сложным для понимания.
Решение: Медиатор берёт на себя роль координатора. Каждый компонент знает только о медиаторе, а не о других компонентах. Когда компоненту нужно что-то сообщить системе, он отправляет событие медиатору, который решает, как на это событие должны отреагировать другие компоненты.
Преимущества:
- Уменьшение связанности: Компоненты становятся независимыми друг от друга.
- Централизация управления: Вся логика взаимодействия находится в одном месте, что упрощает её анализ и изменение.
- Упрощение повторного использования компонентов: Компоненты легче выносить в другие контексты, так как они не зависят от конкретных «коллег».
Недостатки:
- Риск создания «Богатого объекта»: Медиатор может превратиться в монолитный класс, который знает и делает слишком много, нарушая принцип единственной ответственности.
Пример на C# (Упрощённая система диалога в чате):
// 1. Интерфейс Медиатора
public interface IChatMediator
{
void SendMessage(string message, User sender);
void RegisterUser(User user);
}
// 2. Конкретный Медиатор
public class ChatRoom : IChatMediator
{
private List<User> _users = new List<User>();
public void RegisterUser(User user)
{
_users.Add(user);
user.Mediator = this; // Устанавливаем связь «пользователь -> медиатор»
}
public void SendMessage(string message, User sender)
{
// Медиатор решает, как обработать сообщение.
// Здесь он рассылает его всем, кроме отправителя.
foreach (var user in _users)
{
if (user != sender)
{
user.Receive(message, sender.Name);
}
}
// Логику можно легко изменить: отправлять только адресату, фильтровать слова и т.д.
}
}
// 3. Класс «Коллеги» (Colleague), который знает только о Медиаторе
public class User
{
public string Name { get; }
public IChatMediator Mediator { get; set; } // Ссылка на посредника
public User(string name)
{
Name = name;
}
public void Send(string message)
{
Console.WriteLine($"{Name} отправляет: {message}");
// Вместо прямого вызова других пользователей, сообщение отправляется медиатору.
Mediator?.SendMessage(message, this);
}
public void Receive(string message, string senderName)
{
Console.WriteLine($"[{Name}] получил от {senderName}: {message}");
}
}
// 4. Клиентский код
class Program
{
static void Main()
{
// Создаём медиатор (чат-комнату)
IChatMediator chatRoom = new ChatRoom();
// Создаём пользователей
User alice = new User("Alice");
User bob = new User("Bob");
User charlie = new User("Charlie");
// Регистрируем пользователей в медиаторе
chatRoom.RegisterUser(alice);
chatRoom.RegisterUser(bob);
chatRoom.RegisterUser(charlie);
// Пользователи общаются через медиатор
alice.Send("Привет всем!");
// Вывод:
// Alice отправляет: Привет всем!
// [Bob] получил от Alice: Привет всем!
// [Charlie] получил от Alice: Привет всем!
bob.Send("Привет, Alice!");
// Вывод:
// Bob отправляет: Привет, Alice!
// [Alice] получил от Bob: Привет, Alice!
// [Charlie] получил от Bob: Привет, Alice!
}
}