[sw design pattern] Mediator (Mediador)
Os padrões de design GoF são classificados em três categorias: Criacionais, Comportamentais e Estruturais. Os padrões criacionais tratam da criação de objetos, enquanto os padrões estruturais lidam com a estrutura das classes, como herança e composição. Por fim, os padrões comportamentais lidam com a comunicação entre objetos e suas interações. Estes padrões de projeto se encontram no livro “Padrões de Projetos: Soluções Reutilizáveis de Software Orientado a Objetos” escrito por 4 autores denominados GoF (Gang of Four).
O padrão Mediator é um padrão de projeto comportamental que permite a redução das dependências entre objetos, promovendo o baixo acoplamento e facilitando a reutilização de código. Ele é especialmente útil quando você tem um conjunto de objetos que interagem uns com os outros de maneira complexa, e você deseja simplificar essas interações.
No padrão Mediator, um objeto chamado "mediador" é responsável por coordenar a comunicação entre os objetos participantes, conhecidos como "colaboradores". Os colaboradores não se comunicam diretamente entre si, mas sim através do mediador. Isso permite que você altere a interação entre os colaboradores sem precisar modificar os próprios colaboradores.
Abaixo está um exemplo em Java do padrão Mediator:
public interface Mediator {
public void send(String message, Colleague colleague);
}
public class ConcreteMediator implements Mediator {
private Colleague1 colleague1;
private Colleague2 colleague2;
private Colleague3 colleague3;
public void setColleague1(Colleague1 colleague1) {
this.colleague1 = colleague1;
}
public void setColleague2(Colleague2 colleague2) {
this.colleague2 = colleague2;
}
public void setColleague3(Colleague3 colleague3) {
this.colleague3 = colleague3;
}
public void send(String message, Colleague colleague) {
if (colleague == colleague1) {
colleague2.notify(message);
colleague3.notify(message);
} else if (colleague == colleague2) {
colleague1.notify(message);
colleague3.notify(message);
} else if (colleague == colleague3) {
colleague1.notify(message);
colleague2.notify(message);
}
}
}
public abstract class Colleague {
protected Mediator mediator;
public Colleague(Mediator mediator) {
this.mediator = mediator;
}
}
public class Colleague1 extends Colleague {
public Colleague1(Mediator mediator) {
super(mediator);
}
public void send(String message) {
mediator.send(message, this);
}
public void notify(String message) {
System.out.println("Colleague1 gets message: " + message);
}
}
public class Colleague2 extends Colleague {
public Colleague2(Mediator mediator) {
super(mediator);
}
public void send(String message) {
mediator.send(message, this);
}
public void notify(String message) {
System.out.println("Colleague2 gets message: " + message);
}
}
public class Colleague3 extends Colleague {
public Colleague3(Mediator mediator) {
super(mediator);
}
public void send(String message) {
mediator.send(message, this);
}
public void notify(String message) {
System.out.println("Colleague3 gets message: " + message);
}
}
public class MediatorDemo {
public static void main(String[] args) {
ConcreteMediator mediator = new ConcreteMediator();
Colleague1 colleague1 = new Colleague1(mediator);
Colleague2 colleague2 = new Colleague2(mediator);
Colleague3 colleague3 = new Colleague3(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);
mediator.setColleague3(colleague3);
colleague1.send("How are you?");
colleague2.send("Fine, thank you");
}
}
Este exemplo consiste em um mediador que ajuda a manter três colegas em contato. O mediador fornece um método send()
que envia uma mensagem para todos os colegas, exceto para aquele que envia a mensagem. Cada colega tem um método notify()
que recebe a mensagem do mediador. O cliente que usa os colegas e o mediador cria os colegas e define o mediador para cada um deles, então os colegas podem se comunicar por meio do mediador.
O padrão de design Mediator tem relação com outros padrões de design, tanto de criação como de comportamento. Um exemplo de padrão de criação relacionado é o Abstract Factory, pois o Mediator pode ser utilizado para encapsular a criação de objetos em um sistema. Além disso, o padrão de design Command pode ser utilizado em conjunto com o Mediator para implementar a comunicação entre objetos através de comandos. Outro padrão de comportamento relacionado é o Observer, pois o Mediator pode ser utilizado para implementar a comunicação entre objetos em um sistema distribuído, em que os objetos podem ser notificados sobre as mudanças em outros objetos por meio do mediador.
Adicionalmente o padrão de comportamento que pode ser relacionado com o Mediator é o Chain of Responsibility. O Mediator pode ser utilizado como um tipo especial de Chain of Responsibility, onde o objeto mediador é responsável por encaminhar as solicitações dos clientes para os objetos apropriados e garantir que apenas um objeto responda a cada solicitação. Além disso, o Mediator também pode ser utilizado em conjunto com o padrão de design Decorator para adicionar funcionalidades adicionais ao objeto mediador, como log, tratamento de exceções, entre outras. Em resumo, o padrão de design Mediator pode ser utilizado em conjunto com outros padrões de design, tanto de criação como de comportamento, para melhorar a modularidade e a flexibilidade de sistemas orientados a objetos.
links externos com mais exemplos do padrão Mediator:
—> O código no link abaixo apresenta três classes: PowerSupplier
, Button
e Fan
. A classe PowerSupplier
tem dois métodos, turnOn()
e turnOff()
, que implementam ações que podem ser realizadas por um fornecedor de energia. A classe Button
tem uma referência ao Mediator e um método press()
que chama o método press()
da classe Mediator
. A classe Fan
tem uma referência ao Mediator
e um booleano que indica se o ventilador está ligado ou não. Ela também tem os métodos turnOn()
e turnOff()
que chamam os métodos start()
e stop()
, respectivamente, do Mediator
.
O teste unitário apresentado verifica se o ventilador está desligado inicialmente. Em seguida, ele pressiona o botão, verifica se o ventilador está ligado e, em seguida, pressiona o botão novamente e verifica se o ventilador está desligado. Este teste verifica se o padrão Mediator foi implementado corretamente e se o ventilador e o botão estão se comunicando
https://www.baeldung.com/java-mediator-pattern
—> No código descrito no link abaixo, a interface Mediator
define o contrato para a comunicação entre colegas e a classe abstrata Colleague
define o contrato para eventos de notificação do Mediador. A classe ComputerColleague
é um exemplo de implementação concreta de Colleague
e NetworkMediator
é o objeto mediador central que gerencia a comunicação entre diferentes colegas.
O método register
do Mediador adiciona um novo colega à lista de colegas e notifica a todos os outros colegas sobre o novo registro. O método unregister
remove um colega da lista e notifica todos os outros colegas sobre a exclusão. A classe ComputerColleague
implementa os métodos receiveRegisterNotification
e receiveUnRegisterNotification
para processar eventos de notificação recebidos do Mediador
No método main
, o objeto mediator
é criado como uma instância de NetworkMediator
. Em seguida, três instâncias de ComputerColleague
são criadas e registradas no Mediador. Por fim, o primeiro colega é removido do Mediador.
Em resumo, o padrão de projeto Mediator ajuda a desacoplar objetos ao introduzir uma camada intermediária para gerenciar suas interações. O código acima é um exemplo simples deste padrão em ação.
https://riptutorial.com/design-patterns/example/21456/mediator-pattern-example-in-java
REFERÊNCIAS:
https://www.geeksforgeeks.org/mediator-design-pattern/
https://en.wikipedia.org/wiki/Mediator_pattern
https://www.scaler.com/topics/design-patterns/mediator-design-pattern/