El patrón de diseño Mediator es uno de los patrones de diseño conductuales, por lo que trata con los comportamientos de los objetos. Se utiliza para proporcionar un medio de comunicación centralizado entre diferentes objetos en un sistema.
Patrón de Diseño Mediator
Según GoF, la intención del patrón mediador es:
Permite un acoplamiento débil al encapsular la forma en que conjuntos dispares de objetos interactúan y se comunican entre sí. Permite que las acciones de cada conjunto de objetos varíen de forma independiente entre sí.
El patrón de diseño Mediator es muy útil en una aplicación empresarial donde múltiples objetos interactúan entre sí. Si los objetos interactúan directamente entre sí, los componentes del sistema están fuertemente acoplados, lo que aumenta el costo de mantenimiento y dificulta la extensión. El patrón Mediator se centra en proporcionar un mediador entre los objetos para la comunicación y ayudar a implementar un acoplamiento flexible entre los objetos. Un ejemplo excelente del patrón Mediator es el controlador de tráfico aéreo, donde la sala de control del aeropuerto actúa como mediador para la comunicación entre diferentes vuelos. El mediador funciona como un enrutador entre objetos y puede tener su propia lógica para proporcionar una forma de comunicación. Los objetos del sistema que se comunican entre sí se llaman colegas. Por lo general, tenemos una interfaz o clase abstracta que proporciona el contrato para la comunicación y luego tenemos la implementación concreta de los mediadores. Para nuestro ejemplo, intentaremos implementar una aplicación de chat donde los usuarios pueden chatear en grupo. Cada usuario será identificado por su nombre y podrán enviar y recibir mensajes. El mensaje enviado por cualquier usuario debe ser recibido por todos los demás usuarios del grupo.
Interfaz del Patrón Mediator
En primer lugar, crearemos una interfaz de Mediator que definirá el contrato para los mediadores concretos. ChatMediator.java
package com.journaldev.design.mediator;
public interface ChatMediator {
public void sendMessage(String msg, User user);
void addUser(User user);
}
Interfaz de Colega del Patrón Mediador
Los usuarios pueden enviar y recibir mensajes, así que podemos tener una interfaz de usuario o una clase abstracta. Estoy creando Usuario como una clase abstracta de la siguiente manera. 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);
}
Observa que Usuario tiene una referencia al objeto mediador, es necesario para la comunicación entre diferentes usuarios.
Mediador Concreto
Ahora crearemos la clase de mediador concreto, tendrá una lista de usuarios en el grupo y proporcionará la lógica para la comunicación entre los usuarios. 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){
// el mensaje no debe ser recibido por el usuario que lo envía
if(u != user){
u.receive(msg);
}
}
}
}
Colaborador Concreto del Patrón de Diseño de Mediador
Ahora podemos crear clases de Usuario concretas para ser utilizadas por el 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);
}
}
Observa que el método send() está utilizando el mediador para enviar el mensaje a los usuarios y no tiene idea de cómo será manejado por el mediador.
Ejemplo de Código del Programa Cliente del Patrón Mediador
Probemos nuestra aplicación de chat con un programa simple donde crearemos un mediador y agregaremos usuarios al grupo, y uno de los usuarios enviará un mensaje. 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");
}
}
Observa que el programa cliente es muy simple y no tiene idea de cómo se maneja el mensaje ni si el mediador está obteniendo usuarios o no. La salida del ejemplo del patrón mediador es:
Pankaj: Sending Message=Hi All
Lisa: Received Message:Hi All
Saurabh: Received Message:Hi All
David: Received Message:Hi All
Diagrama de Clase del Patrón Mediador
Ejemplo de Patrón Mediador en JDK
- La clase java.util.Timer tiene métodos scheduleXXX()
- El Executor de Concurrencia de Java tiene el método execute().
- El método invoke() de la clase java.lang.reflect.Method.
Puntos Importantes del Patrón de Diseño Mediador
- El patrón mediador es útil cuando la lógica de comunicación entre objetos es compleja, podemos tener un punto central de comunicación que se encargue de la lógica de comunicación.
- Java Message Service (JMS) utiliza el patrón mediador junto con el patrón Observador para permitir que las aplicaciones se suscriban y publiquen datos a otras aplicaciones.
- No deberíamos usar el patrón mediador solo para lograr un acoplamiento laxo, porque si el número de mediadores crece, entonces será difícil mantenerlos.
Eso es todo para el patrón de diseño mediador y su implementación en Java.
Source:
https://www.digitalocean.com/community/tutorials/mediator-design-pattern-java