Introdução
O Mediator é um padrão de design comportamental (do catálogo GoF). Seu objetivo é reduzir o acoplamento direto entre objetos, centralizando a comunicação em um objeto intermediário chamado mediador.
Em sistemas grandes vários objetos interagem entre si. Se cada objeto se comunicar diretamente com os outros, o sistema fica aclopado como uma “teia” de dependências difícil de manter. O Mediador entra nesse cenário, e atua como um “hub”, onde em vez de os objetos conversarem entre si diretamente, eles falam com o mediador, que decide para onde a mensagem vai.
Analogia
Imagine um aeroporto:
- Os pilotos não ficam falando uns com os outros diretamente pelo rádio
- Eles falam com a torre de controle (o mediador)
- A torre organiza e coordena a comunicação, evitando conflitos
Estrutura do Mediator
- Mediator (interface/abstração): define como os colegas (colleagues) se comunicam atráves dele
- ConcreteMediator: Implementa a lógica de coordenação
- Colleagues: objetos que dependem do mediador para interagir
Exemplo prático
A seguir tratrei dois exemplos práticos. O primeiro considera o método tradicional de comunicação entre a comunicação de objetos, e o segundo com o padrão Mediator implementado.
Sem Mediator
No exemplo abaixo, dois módulos (chat de usuários) se comunicam diretamente entre si:
public class Usuario
{
public string Nome { get; }
public Usuario(string nome)
{
Nome = nome;
}
public void EnviarMensagem(string msg, Usuario destinatario)
{
destinatario.ReceberMensagem($"{Nome}: {msg}");
}
public void ReceberMensagem(string msg)
{
Console.WriteLine(msg);
}
}
// Uso:
var ana = new Usuario("Ana");
var bruno = new Usuario("Bruno");
ana.EnviarMensagem("Olá, Bruno!", bruno);
bruno.EnviarMensagem("Oi, Ana!", ana);
- Cada usuário precisa conhecer os outros.
- Se quisermos adicionar regras de negócio (como logs, bloqueios, histórico, filtros, etc.), teremos que alterar o código de todos os objetos que enviam mensagens.
- O sistema rapidamente se torna difícil de manter.
Com Mediator
Agora introduzimos um ChatMediator para intermediar as mensagens:
// Interface do Mediator
public interface IChatMediator
{
void EnviarMensagem(string mensagem, Usuario usuario);
void AdicionarUsuario(Usuario usuario);
}
// Implementação concreta do Mediator
public class ChatMediator : IChatMediator
{
private readonly List<Usuario> _usuarios = new();
public void AdicionarUsuario(Usuario usuario) => _usuarios.Add(usuario);
public void EnviarMensagem(string mensagem, Usuario usuario)
{
foreach (var u in _usuarios)
{
if (u != usuario)
u.ReceberMensagem(mensagem);
}
}
}
// Colleague
public class Usuario
{
private readonly IChatMediator _mediator;
public string Nome { get; }
public Usuario(string nome, IChatMediator mediator)
{
Nome = nome;
_mediator = mediator;
_mediator.AdicionarUsuario(this);
}
public void EnviarMensagem(string msg)
{
_mediator.EnviarMensagem($"{Nome}: {msg}", this);
}
public void ReceberMensagem(string msg)
{
Console.WriteLine(msg);
}
}
// Uso:
var chat = new ChatMediator();
var ana = new Usuario("Ana", chat);
var bruno = new Usuario("Bruno", chat);
ana.EnviarMensagem("Olá, Bruno!");
bruno.EnviarMensagem("Oi, Ana!");
- Os usuários não conhecem uns aos outros, apenas o mediador.
- Regras como logs, histórico, notificações ou moderação podem ser implementadas no mediador, sem alterar as classes de usuário.
- O sistema fica mais coeso e desacoplado
No .NET moderno, esse padrão é muito utilizado através da biblioteca MediatR, que implementa o conceito para lidar com commands e queries em arquitetura como **CQRS** e Clean Architecture.
Top comments (0)