Padrão de Projeto Mediator
O padrão de design Mediator é um dos padrões de design comportamentais, portanto, lida com os comportamentos dos objetos. Ele é usado para fornecer um meio de comunicação centralizado entre diferentes objetos em um sistema. De acordo com GoF, a intenção do padrão Mediator é permitir um acoplamento flexível encapsulando a maneira como conjuntos díspares de objetos interagem e se comunicam entre si. Isso permite que as ações de cada conjunto de objetos variem independentemente umas das outras.
O padrão de design Mediator é muito útil em uma aplicação empresarial onde vários objetos estão interagindo entre si. Se os objetos interagem diretamente uns com os outros, os componentes do sistema estão fortemente acoplados, o que aumenta o custo de manutenção e torna a extensão mais difícil. O padrão Mediator foca em fornecer um mediador entre os objetos para comunicação e ajuda na implementação de um baixo acoplamento entre eles. Um controlador de tráfego aéreo é um ótimo exemplo do padrão Mediator, onde a sala de controle do aeroporto atua como um mediador para a comunicação entre diferentes voos. O mediador funciona como um roteador entre os objetos e pode ter sua própria lógica para fornecer um meio de comunicação. Os objetos do sistema que se comunicam entre si são chamados de Colegas. Normalmente, temos uma interface ou classe abstrata que fornece o contrato para comunicação e depois temos a implementação concreta dos mediadores. Para nosso exemplo, vamos tentar implementar um aplicativo de chat onde os usuários podem conversar em grupo. Cada usuário será identificado por seu nome e eles podem enviar e receber mensagens. A mensagem enviada por qualquer usuário deve ser recebida por todos os outros usuários do grupo.
Interface do Padrão Mediator
Primeiro, vamos criar a interface Mediator que definirá o contrato para mediadores concretos. ChatMediator.java
package com.journaldev.design.mediator;
public interface ChatMediator {
public void sendMessage(String msg, User user);
void addUser(User user);
}
Interface do Colega do Padrão Mediador
Os usuários podem enviar e receber mensagens, então podemos ter uma interface de Usuário ou uma classe abstrata. Estou criando o Usuário como uma classe abstrata como abaixo. User.java
package com.journaldev.design.mediator;
public abstract class User {
protected ChatMediator mediator;
protected String name;
public User(ChatMediator med, String name){
this.mediator=med;
this.name=name;
}
public abstract void send(String msg);
public abstract void receive(String msg);
}
Observe que o Usuário tem uma referência ao objeto mediador, é necessário para a comunicação entre diferentes usuários.
Mediador Concreto
Agora vamos criar a classe de mediador concreto, ela terá uma lista de usuários no grupo e fornecerá a lógica para a comunicação entre os usuários. ChatMediatorImpl.java
package com.journaldev.design.mediator;
import java.util.ArrayList;
import java.util.List;
public class ChatMediatorImpl implements ChatMediator {
private List users;
public ChatMediatorImpl(){
this.users=new ArrayList<>();
}
@Override
public void addUser(User user){
this.users.add(user);
}
@Override
public void sendMessage(String msg, User user) {
for(User u : this.users){
// a mensagem não deve ser recebida pelo usuário que a enviou
if(u != user){
u.receive(msg);
}
}
}
}
Colaborador Concreto do Padrão de Projeto Mediador
Agora podemos criar classes de Usuário concretas para serem usadas pelo sistema cliente. UserImpl.java
package com.journaldev.design.mediator;
public class UserImpl extends User {
public UserImpl(ChatMediator med, String name) {
super(med, name);
}
@Override
public void send(String msg){
System.out.println(this.name+": Sending Message="+msg);
mediator.sendMessage(msg, this);
}
@Override
public void receive(String msg) {
System.out.println(this.name+": Received Message:"+msg);
}
}
Observe que o método send() está usando o mediador para enviar a mensagem aos usuários e não tem ideia de como ela será tratada pelo mediador.
Exemplo de Código do Programa Cliente do Padrão Mediador
Vamos testar nossa aplicação de chat com um programa simples onde criaremos um mediador, adicionaremos usuários ao grupo e um dos usuários enviará uma mensagem. ChatClient.java
package com.journaldev.design.mediator;
public class ChatClient {
public static void main(String[] args) {
ChatMediator mediator = new ChatMediatorImpl();
User user1 = new UserImpl(mediator, "Pankaj");
User user2 = new UserImpl(mediator, "Lisa");
User user3 = new UserImpl(mediator, "Saurabh");
User user4 = new UserImpl(mediator, "David");
mediator.addUser(user1);
mediator.addUser(user2);
mediator.addUser(user3);
mediator.addUser(user4);
user1.send("Hi All");
}
}
Observe que o programa cliente é muito simples e não tem ideia de como a mensagem está sendo tratada e se o mediador está recebendo o usuário ou não. A saída do exemplo de programa do padrão mediador é:
Pankaj: Sending Message=Hi All
Lisa: Received Message:Hi All
Saurabh: Received Message:Hi All
David: Received Message:Hi All
Diagrama de Classe do Padrão Mediador
Exemplo de Padrão Mediador no JDK
- Classe java.util.Timer métodos scheduleXXX()
- Executor de Concorrência Java método execute().
- método invoke() da classe java.lang.reflect.Method.
Pontos Importantes do Padrão de Projeto Mediador
- O padrão de projeto Mediador é útil quando a lógica de comunicação entre objetos é complexa, podemos ter um ponto central de comunicação que cuida da lógica de comunicação.
- O Java Message Service (JMS) utiliza o padrão Mediador juntamente com o padrão Observador para permitir que as aplicações se inscrevam e publiquem dados para outras aplicações.
- Não devemos usar o padrão mediador apenas para alcançar o desacoplamento, porque se o número de mediadores aumentar, será difícil mantê-los.
Isso é tudo para o padrão de projeto do mediador e sua implementação em Java.
Source:
https://www.digitalocean.com/community/tutorials/mediator-design-pattern-java