Definição
O Padrão Mediador é utilizado para reduzir a complexidade de comunicação entre múltiplos objetos e classes. Este padrão fornece uma classe mediadora que geralmente lida com a comunicação entre diferentes classes, suportando baixo acoplamento e tronando o código mais fácil de manter.
Características
Centraliza a forma complexa de comunicação e controle entre objetos relacionados.
Cenários de Uso
- Quando existe uma estrutura em rede complexa entre objetos, resultando em dependências confusas e difíceis de reutilizar.
- Quando se deseja criar um objeto que opera entre várias classes sem gerar novas subclasses.
Vantagens e Desvantagens
Vantagens
- Reduz a complexidade das classes, transformando relações muitos-para-muitos em relações um-para-um.
- Desacopla as classes entre si.
Desvantagens
- O mediador pode se tornar grande, complexo e difícil de manter.
Estrutura do Padrão
- Interface do Mediador (Mediator): É a interface do mediador, fornecendo métodos abstratos para registrar objetos colegas e ancaminhar informações entre eles.
- Mediador Concreto (ChatPlatform): Implementa a interface do mediador, define uma Lista para gerenciar objetos colega e协调a as interações entre eles, dependendo assim dos objetos colega.
- Classe Abstrata do Colega (User): Define a interface da classe colega, mantém um objeto mediador, fornece métodos abstratos para interação entre objetos colega e implementa funcionalidades comuns a todas as classes colegas que se influenciam mutuamente.
- Classe Concreta do Colega (NormalUser): Implementa a classe abstrata do colega. Quando precisa interagir com outros objetos colega, o objeto mediador é responsável pela interação subsequente.
Implementação Concreta
Mediador
/**
* Interface do Mediador
*/
public interface Mediator {
/**
* Enviar mensagem para todos
*/
void broadcastMessage(String message, String sender);
/**
* Enviar mensagem para um usuário específico
*/
void sendPrivateMessage(String message, String sender, String recipient);
/**
* Registrar um novo participante
*/
void registerParticipant(Participant participant);
/**
* Remover um participante
*/
void removeParticipant(Participant participant);
}
/**
* Implementação concreta do mediador - Plataforma de Comunicação
*/
public class CommunicationPlatform implements Mediator {
private List<Participant> participants = new ArrayList<>();
@Override
public void broadcastMessage(String message, String sender) {
for (Participant p : participants) {
if (!p.getName().equals(sender)) {
p.receiveMessage(message, "Broadcast de " + sender);
}
}
}
@Override
public void sendPrivateMessage(String message, String sender, String recipient) {
for (Participant p : participants) {
if (p.getName().equals(recipient)) {
p.receiveMessage(message, "Mensagem privada de " + sender);
break;
}
}
}
@Override
public void registerParticipant(Participant participant) {
participants.add(participant);
}
@Override
public void removeParticipant(Participant participant) {
participants.remove(participant);
}
}
Classe Colega
/**
* Interface do Participante
*/
public interface Participant {
/**
* Enviar mensagem para todos
*/
void sendMessageToAll(String message);
/**
* Enviar mensagem privada
*/
void sendPrivateMessage(String message, String recipient);
/**
* Receber mensagem
*/
void receiveMessage(String message, String sender);
/**
* Obter nome do participante
*/
String getName();
/**
* Entrar na plataforma
*/
void enterPlatform();
/**
* Sair da plataforma
*/
void exitPlatform();
}
/**
* Participante comum
*/
public class RegularParticipant implements Participant {
private Mediator mediator;
private String name;
public RegularParticipant(String name, Mediator mediator) {
this.name = name;
this.mediator = mediator;
}
@Override
public void sendMessageToAll(String message) {
mediator.broadcastMessage(message, this.name);
}
@Override
public void sendPrivateMessage(String message, String recipient) {
mediator.sendPrivateMessage(message, this.name, recipient);
}
@Override
public void receiveMessage(String message, String sender) {
System.out.println("[" + this.name + "] Recebido de " + sender + ": " + message);
}
@Override
public String getName() {
return this.name;
}
@Override
public void enterPlatform() {
mediator.registerParticipant(this);
System.out.println(this.name + " entrou na plataforma.");
}
@Override
public void exitPlatform() {
mediator.removeParticipant(this);
System.out.println(this.name + " saiu da plataforma.");
}
}
Uso Concreto
/**
* Classe de teste do Padrão Mediador
*/
public class Demo {
public static void main(String[] args) {
Mediator platform = new CommunicationPlatform();
Participant alice = new RegularParticipant("Alice", platform);
Participant bob = new RegularParticipant("Bob", platform);
Participant charlie = new RegularParticipant("Charlie", platform);
alice.enterPlatform();
bob.enterPlatform();
charlie.enterPlatform();
System.out.println("\n=== Alice envia mensagem para todos ===");
alice.sendMessageToAll("Olá a todos, alguém me ouve?");
System.out.println("\n=== Alice envia mensagem privada para Bob ===");
alice.sendPrivateMessage("Bob, só quero falar contigo", "Bob");
System.out.println("\n=== Bob responde a Alice ===");
bob.sendPrivateMessage("Alice, claro, pode falar", "Alice");
System.out.println("\n=== Alice sai da plataforma ===");
alice.exitPlatform();
System.out.println("\n=== Bob envia mensagem para todos ===");
bob.sendMessageToAll("Alice, você ainda está aí?");
}
}
Aplicações Reais
- Frameworks MVC, onde o C (Controlador) atua como mediador entre o M (Modelo) e a V (Visualização).
- Agendadores de tarefas:
- Todos os métodos scheduleXXX() de java.util.Timer
- O método java.util.concurrent.Executor#execute()
- Métodos submit() e invokeXXX() de java.util.concurrent.ExecutorService
- Métodos scheduleXXX() de java.util.concurrent.ScheduledExecutorService