ComportamentalIntermediário6 min de leitura9 seções1994, Marco de referência: a ideia é mais velha que a data

Mediator

Concentra num objeto as regras de interação entre vários componentes, que passam a conversar através dele em vez de se conhecerem diretamente.

Em 10 segundos

Em vez de o campo de destino conhecer o de data, que conhece o botão, todos avisam um mediador. Ele guarda as regras — 'trocar destino limpa a data', 'botão só habilita com os dois preenchidos' — e a teia de dependências vira uma estrela.

  • #acoplamento
  • #coordenacao
  • #ui
  • #gof
Analogia

A torre de controle

Pilotos não negociam pista entre si por rádio; seria caos com dez aviões e impossível com cem. Todos falam com a torre, que conhece a posição de cada um e dá as ordens. Nenhum piloto precisa saber quem mais está no ar — e um avião novo entra no espaço aéreo sem que ninguém seja apresentado a ele.

01Conceito

O problema

Coordenação entre componentes tende a virar conhecimento mútuo. Cada regra nova adiciona uma referência, e o número de ligações cresce muito mais rápido que o número de peças.

O efeito colateral é que nenhum componente é reaproveitável: ele só compila junto com os colegas que aprendeu a chamar.

A comparação inevitável é com Observer, e a diferença é onde mora a regra. No Observer, o sujeito emite um evento e os observadores decidem sozinhos o que fazer — a lógica fica distribuída entre eles, e o sujeito não sabe nem quantos existem. No Mediator, os colegas apenas relatam, e a decisão sobre o que acontece em consequência é do mediador, num lugar só.

Isso torna os padrões complementares, não concorrentes: é muito comum implementar o canal de avisos com Observer e a lógica de reação com Mediator. O que importa é responder à pergunta 'onde vive a regra de interação?'.

Com Facade a distinção é de direção. A facade simplifica o acesso de fora para dentro, e o subsistema nem sabe que ela existe. O mediador coordena de dentro, e os colegas o conhecem explicitamente. Facade é uma porta; mediador é um centro nervoso.

02Conceito

O risco embutido: centralizar demais

O padrão troca muitas conexões por um ponto central — e esse ponto tende a engordar. É o único padrão do GoF cujo principal risco é o sucesso do próprio uso.

Cada regra nova de interação vai naturalmente para o mediador, porque é onde as regras moram. Depois de um ano, ele conhece quinze componentes e tem oitocentas linhas de condicionais — o god object que o padrão veio evitar, agora com um nome respeitável.

O contorno é dividir por contexto em vez de por tela: um mediador por grupo coeso de componentes, não um por aplicação. Se dois grupos não têm regras entre si, não devem compartilhar mediador.

O sinal de que passou do ponto é o mediador precisar consultar o estado de vários colegas para decidir cada coisa. Quando isso acontece, a lógica provavelmente é de domínio e deveria estar num modelo próprio, com o mediador apenas refletindo o resultado na interface.

Sem o padrão × com o padrão

Com Mediator: uma estrela

  • cada componente conhece só o mediador
  • as regras de interação ficam num lugar só
  • componentes viram reaproveitáveis em outras telas
  • testar uma regra é testar o mediador com colegas falsos

O custo é a centralização: o mediador concentra conhecimento e tende a engordar. Sem disciplina para dividi-lo por contexto, ele vira o gargalo de manutenção.

O padrão não elimina a complexidade da coordenação — ele a reúne. Isso é bom enquanto o conjunto for coeso e ruim quando o mediador vira depósito de regras não relacionadas.
Como se organiza
  • DialogoReserva (mediador)conhece todos e guarda as regras

    • Campo destinoavisa 'mudou' e nada mais

    • Campo dataavisa 'mudou' e nada mais

    • Botão reservarsó obedece ao mediador

As setas que existiriam entre os três colegas desapareceram: nenhum deles tem referência aos outros, só ao centro. É isso que os torna reaproveitáveis fora desta tela.
Passo a passoO fluxo, passo a passo
  1. 1

    Colega só relata

    Cada componente avisa o mediador quando algo muda — sem conhecer os outros.

  2. 2

    Mediador recebe

    O centro concentra as regras: quem limpa o quê, quem habilita o botão.

  3. 3

    Coordena os demais

    A partir do aviso, o mediador atualiza os colegas necessários.

  4. 4

    Reaproveitar

    O mesmo Campo serve em outro diálogo: a regra de interação fica no mediador daquela tela.

03Anatomia

Navegue pelas camadas

Camada 1/2Colega

Camada 1

Colega

relata, não decide

Cuida do próprio comportamento e avisa o mediador quando algo relevante acontece. Não conhece os outros componentes nem as consequências do que reporta — é isso que permite usá-lo em outro contexto.

No código

digitar(v) { this.valor = v; this.mediador.notificar('destino', 'mudou') }

Se violar: colega que chama outro colega direto 'só neste caso' recriou a teia — e a exceção vira regra em poucos meses.

04Estrutura

Estrutura

Diagrama de classes
05Implementação

Código

interface Mediador {
  notificar(origem: string, evento: string): void;
}

class Campo {
  valor = "";
  habilitado = true;
  constructor(
    private nome: string,
    private mediador: Mediador,
  ) {}

  digitar(v: string): void {
    this.valor = v;
    // o campo nao sabe quem se importa — so avisa
    this.mediador.notificar(this.nome, "mudou");
  }
}

// O mediador concentra TODAS as regras de interacao
class DialogoReserva implements Mediador {
  destino = new Campo("destino", this);
  data = new Campo("data", this);
  botao = { habilitado: false };

  notificar(origem: string, evento: string): void {
    if (evento !== "mudou") return;

    // regra 1: trocar o destino invalida a data escolhida
    if (origem === "destino") this.data.valor = "";

    // regra 2: so libera o botao com os dois preenchidos
    this.botao.habilitado = Boolean(this.destino.valor && this.data.valor);
  }
}

const d = new DialogoReserva();
d.destino.digitar("Lisboa");
d.data.digitar("2026-09-01");
console.log(d.botao.habilitado); // true
06No mundo real

Casos de uso

Formulário com campos interdependentes

Cenário

Numa reserva de viagem, escolher o destino filtra as datas disponíveis, a data altera as tarifas, e o botão de confirmar só habilita quando tudo está coerente.

Como o padrão entra

Um mediador do diálogo recebe os avisos de cada campo e aplica as regras de dependência. Os campos viram componentes genéricos, usáveis em qualquer formulário.

Trade-off: Regras de dependência complexas tornam o mediador difícil de ler, e a ordem em que ele atualiza os colegas passa a importar — atualizar o botão antes de limpar a data produz um estado momentâneo inválido.

Sala de chat

Cenário

Participantes enviam mensagens que devem chegar aos demais, com regras de silenciamento, banimento e histórico.

Como o padrão entra

A sala é o mediador: recebe a mensagem de um participante e decide para quem entregar, aplicando as regras. Nenhum participante tem referência a outro — é o exemplo canônico do padrão.

Trade-off: Como todo tráfego passa pelo centro, ele vira o gargalo de desempenho e o ponto único de falha; escalar a sala exige quebrá-la em várias ou distribuir o estado.

Coordenação entre widgets de um painel

Cenário

Num dashboard, selecionar uma região no mapa filtra o gráfico de vendas, que ajusta a tabela, que atualiza os totais.

Como o padrão entra

Um mediador do painel recebe as seleções e propaga os filtros para os widgets interessados. Cada widget continua sendo um componente independente, testável e reaproveitável.

Trade-off: Propagações em cadeia podem gerar laços (o gráfico ajusta a tabela, que reajusta o gráfico) — o mediador precisa de proteção contra reentrância, algo que raramente se prevê na primeira versão.

O mediador que os colegas ignoram

Compila, roda, passa no code review. E quebra depois.

O mediador está no diagrama, mas o campo ainda segura referência ao colega e aplica a regra 'só neste caso'. A teia volta; o centro vira burocracia.

class Campo {
  valor = "";
  constructor(
    private nome: string,
    private mediador: Mediador,
    private data?: Campo, // <- ainda conhece o colega
  ) {}

  digitar(v: string) {
    this.valor = v;
    this.mediador.notificar(this.nome, "mudou");
    // "so neste caso" — a teia voltou pela porta dos fundos
    if (this.nome === "destino" && this.data) this.data.valor = "";
  }
}

// O mediador existe, mas o campo continua coordenando.
// Reaproveitar Campo noutro dialogo leva a data junto.

O que quebra

  • Ao reusar o campoEle carrega dependências do diálogo antigo e não compila sozinho.
  • Ao mudar a regraParte vive no mediador, parte no colega — as duas saem de sincronia.
  • No testeTestar um Campo exige montar os colegas que ele ainda conhece.

A saída: Colega só notifica; regra de interação só no mediador. Se a exceção 'direta' parecer inevitável, a fronteira do mediador está errada — não a regra do padrão.

08Cuidado

Armadilhas

  1. O mediador vira god object

    É a armadilha principal e quase inevitável sem disciplina: como toda regra de interação pertence ao mediador, ele cresce sem limite natural. Quando passar de algumas centenas de linhas ou coordenar mais de meia dúzia de colegas, divida por contexto — vários mediadores pequenos são melhores que um onisciente.

  2. Notificações em laço

    O mediador reage a um aviso alterando um colega, que emite outro aviso, que faz o mediador alterar o primeiro. Sem guarda de reentrância, isso vira recursão infinita ou piscada visível na interface. Alterações feitas pelo mediador precisam ser silenciosas ou marcadas para não realimentarem o ciclo.

  3. Confundir com Observer e perder os dois

    Usar Observer esperando coordenação central espalha a regra entre os observadores; usar Mediator para simples difusão de eventos cria um centro sem propósito. A pergunta que resolve: existe regra sobre COMO os componentes reagem juntos? Se sim, Mediator. Se cada um decide sozinho, Observer.

09Decisão

Quando usar × quando evitar

Use quando

3
  • Componentes se coordenam com regras que não pertencem a nenhum deles.
  • Você quer reaproveitar peças que hoje conhecem os colegas.
  • As regras de interação mudam bastante e estão espalhadas.

Evite quando

3
  • São dois componentes e uma regra simples.
  • É difusão de eventos sem regra entre receptores — use Observer.
  • O conjunto é grande e sem coesão: o mediador viraria um depósito.

Testar o que ficou

3 armadilhas de Mediator viram perguntas, com o nome do padrão escondido, misturadas com padrões parecidos.

Onde isto aparece de verdade

Você já usa isto, talvez sem saber o nome.

  • A store do ReduxComponentes não conversam entre si: todos falam com a store, que coordena as consequências.
  • Um event busPublicadores e assinantes se desconhecem; o barramento no meio é quem sabe ligar os dois.

O padrão em uma linha

Sem nome de domínio, sem cerimônia. Só a ideia.

// Colegas falam com o mediador, não entre si.
mediador.notificar(this, "clique");

O que ele cobra

1 salto a mais entre a chamada e o efeito.

  • O mediador tende a concentrar lógica e crescer até virar um objeto-deus difícil de manter
  • Uma indireção a mais entre colegas que antes se falavam diretamente

Não vale se: há poucos componentes e a comunicação entre eles é simples — centralizar tudo só cria um gargalo de manutenção.

Costuma ser confundido com

Onde isto aparece

Continue por aqui