O padrão Mediator é um padrão de design comportamental que tem como objetivo principal simplificar a comunicação e interações entre múltiplos objetos ou componentes em um sistema. O padrão Mediator resolve vários problemas relacionados à complexidade de comunicação em sistemas com muitos componentes interconectados:

  1. Reduz a Complexidade de Comunicação: Em sistemas onde cada componente se comunica diretamente com muitos outros, a complexidade das interações pode aumentar exponencialmente. O Mediator centraliza essa comunicação, reduzindo a complexidade de interconexões diretas.

  2. Promove o Baixo Acoplamento: Ao desacoplar os componentes uns dos outros e fazê-los se comunicar através de um mediador, o padrão ajuda a reduzir as dependências diretas entre eles, facilitando a manutenção e a evolução do sistema.

  3. Gerenciamento Centralizado de Interações: O Mediator atua como um ponto central para controlar e gerenciar como os diferentes componentes interagem, tornando mais fácil entender e modificar o fluxo de comunicação no sistema.

  4. Reutilização e Isolamento dos Componentes: Como os componentes não dependem uns dos outros diretamente, eles se tornam mais reutilizáveis e podem ser testados de forma isolada mais facilmente.

Como Funciona

O padrão Mediator envolve principalmente dois tipos de componentes:

  • Mediator (Interface ou Classe Abstrata): Define uma interface para a comunicação com os objetos componentes. O mediador conhece e mantém referências aos componentes com os quais precisa interagir.
  • Concrete Mediator: Implementa a interface Mediator e coordena a comunicação entre os componentes concretos. Pode processar e rotear mensagens de um componente para outro.
  • Componentes: São classes que realizam suas funções específicas e se comunicam com outros componentes por meio do mediador. Eles não se comunicam diretamente uns com os outros, mas enviam mensagens ou chamam métodos do mediador.

Exemplo

Um exemplo clássico do uso do padrão Mediator é em sistemas de interface de usuário, onde diversos componentes (como botões, menus, caixas de texto) precisam interagir entre si. Ao invés de cada componente conhecer e interagir diretamente com os outros, um objeto mediador gerencia essas interações, simplificando as relações entre os componentes da interface.

Exemplo de Implementação

Claro! Vamos criar um exemplo simples do padrão Mediator em Java. Vamos desenvolver um sistema de chat onde os usuários podem enviar mensagens uns aos outros através de um mediador central.

Interface Mediator

Primeiro, definimos a interface Mediator:

public interface Mediator {
    void enviarMensagem(String msg, Usuario usuario);
}

Classe Concrete Mediator

Implementamos o ConcreteMediator para o chat:

import java.util.ArrayList;
import java.util.List;
 
public class ChatMediator implements Mediator {
    private List<Usuario> usuarios;
 
    public ChatMediator() {
        this.usuarios = new ArrayList<>();
    }
 
    public void adicionarUsuario(Usuario usuario) {
        this.usuarios.add(usuario);
    }
 
    @Override
    public void enviarMensagem(String msg, Usuario usuario) {
        for (Usuario u : usuarios) {
            // O usuário não deve receber sua própria mensagem
            if (u != usuario) {
                u.receber(msg);
            }
        }
    }
}

Todos os usuários no chat recebem todas as mensagens enviadas, exceto o próprio usuário que enviou a mensagem. O Mediator, neste caso o ChatMediator, é responsável por distribuir as mensagens para todos os usuários registrados no chat. A lógica para isso está no método enviarMensagem da classe ChatMediator

Classe Component

A classe Usuario atua como o componente:

public class Usuario {
    private String nome;
    private Mediator mediator;
 
    public Usuario(String nome, Mediator mediator) {
        this.nome = nome;
        this.mediator = mediator;
    }
 
    public void enviar(String msg) {
        System.out.println(this.nome + ": Enviando Mensagem = " + msg);
        mediator.enviarMensagem(msg, this);
    }
 
    public void receber(String msg) {
        System.out.println(this.nome + ": Mensagem Recebida = " + msg);
    }
}

Testando o Padrão Mediator

Vamos criar um chat e adicionar usuários ao mediador:

public class Main {
    public static void main(String[] args) {
        ChatMediator mediator = new ChatMediator();
        
        Usuario ana = new Usuario("Ana", mediator);
        Usuario bruno = new Usuario("Bruno", mediator);
        Usuario carla = new Usuario("Carla", mediator);
 
        mediator.adicionarUsuario(ana);
        mediator.adicionarUsuario(bruno);
        mediator.adicionarUsuario(carla);
 
        ana.enviar("Oi, pessoal!");
        bruno.enviar("Olá, Ana!");
        carla.enviar("Bom dia a todos!");
    }
}

Neste exemplo, a classe ChatMediator atua como um mediador central, gerenciando a comunicação entre os objetos Usuario. Cada usuário envia mensagens através do mediador, que as redistribui para os outros usuários. Isso ilustra como o padrão Mediator facilita a comunicação entre objetos, sem que eles precisem se referir uns aos outros diretamente.