Mediator
Propósito
Define un objeto que encapsula cómo interactúan un conjunto de objetos. Promueve un bajo acoplamiento al evitar que los objetos se refieran unos a otros explícitamente, y permite variar la interacción entre ellos de forma independiente.
Motivación
Cuando muchos objetos interactúan con otros objetos, se puede formar una estructura muy compleja, con objetos con muchas conexiones con otros objetos. En un caso extremo cada objeto puede conocer a todos los demás objetos. Para evitar esto el patrón Mediator encapsula el comportamiento de todo un conjunto de objetos en un solo objeto.
Los objetos envían y reciben peticiones a través del mediador, este patrón implementa el comportamiento cooperativo encaminando esas peticiones a los objetos apropiados.
Aplicabilidad
Utilizaremos el patrón Mediator cuando:
- Un conjunto grande de objetos se comunica de una forma bien definida, pero compleja.
- Dificultad para reutilizar objetos ya que nos referimos a varios objetos para comunicarnos.
- El comportamiento de muchos objetos que esta distribuido entre varias clases, puede resumirse en una o varias por subclasificación.
Estructura
Participantes
- Mediator: define una interface para comunicarse con los objetos colegas.
- ConcreteMediator: Implementa el comportamiento cooperativo entre los colegas (como se comunican entre ellos). Además los conoce y mantiene.
- Colleagues classes: Cada colega conoce su mediador, y usa a este para comunicarse con otros colegas.
Colaboraciones
Los objetos (Colegas) envían y reciben requerimientos (requests) de un objeto mediador. El mediador implementa como se comunican los objetos.
Consecuencias
Ventajas e inconvenientes del patrón Mediator:
- Reduce herencia. Con una subclase llamada Mediador cambiamos el comportamiento, que de otra manera estaría distribuido en varios objetos.
- Desacopla a los objetos. El patrón Mediator promueve bajar el acoplamiento entre objetos. Se puede variar y rehusar objetos y mediadores independientemente.
- Simplifica la comunicación entre objetos. Los objetos que se comunican de la forma "muchos a muchos" puede ser remplazada por una forma "uno a muchos" que es menos compleja y más elegante. Además esta forma de comunicación es más fácil de entender.Abstrae como los objetos cooperan. Haciendo a la mediación un concepto independiente y encapsulándolo en un objeto permite enfocar como los objetos interactúan. Esto ayuda a clarificar como los objetos se relacionan en un sistema.
- Centraliza el control. El mediador es el que se encarga de comunicar a los objetos, este puede ser muy complejo, difícil de entender y modificar.
Implementación
Es importante tener en cuenta en la implementación de este patrón:
- Omitir la clase abstracta Mediator. No es necesario crear una clase abstracta Mediador cuando los objetos solo trabajan con un mediador. El acoplamiento abstracto de dicha clase permite que los objetos trabajen con diferentes subclases Mediator y viceversa.
- Comunicación Objeto y Mediador. Los objetos se comunican su mediador cuanto tiene lugar un evento. Las clases de objetos cada vez que cambian su estado envían notificaciones al mediador. El mediador responde propagando los efectos de dichos eventos a los otros objetos.Otra forma define al Mediador una interfaz de notificación especializada que permite a los objetos ser más directos en su comunicación.
Código de ejemplo
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
//Interfaz Amigo
interface Command {
void execute();
}
//Mediador Abstracto
interface IMediator {
void book();
void view();
void search();
void registerView(BtnView
v);
void
registerSearch(BtnSearch s);
void registerBook(BtnBook
b);
void
registerDisplay(LblDisplay d);
}
//Mediador Concreto
class Mediator implements IMediator {
BtnView btnView;
BtnSearch
btnSearch;
BtnBook btnBook;
LblDisplay show;
//....
void registerView(BtnView
v) {
btnView = v;
}
void
registerSearch(BtnSearch s) {
btnSearch = s;
}
void registerBook(BtnBook
b) {
btnBook = b;
}
void
registerDisplay(LblDisplay d) {
show = d;
}
void book() {
btnBook.setEnabled(false);
btnView.setEnabled(true);
btnSearch.setEnabled(true);
show.setText("booking...");
}
void view() {
btnView.setEnabled(false);
btnSearch.setEnabled(true);
btnBook.setEnabled(true);
show.setText("viewing...");
}
void search() {
btnSearch.setEnabled(false);
btnView.setEnabled(true);
btnBook.setEnabled(true);
show.setText("searching...");
}
}
//Un amigo concreto
class BtnView extends JButton implements Command {
IMediator med;
BtnView(ActionListener
al, IMediator m) {
super("View");
addActionListener(al);
med = m;
med.registerView(this);
}
public void
execute() {
med.view();
}
}
//Un amigo concreto
class BtnSearch extends JButton implements Command {
IMediator med;
BtnSearch(ActionListener
al, IMediator m) {
super("Search");
addActionListener(al);
med = m;
med.registerSearch(this);
}
public void
execute() {
med.search();
}
}
//Un amigo concreto
class BtnBook extends JButton implements Command {
IMediator med;
BtnBook(ActionListener
al, IMediator m) {
super("Book");
addActionListener(al);
med = m;
med.registerBook(this);
}
public void execute() {
med.book();
}
}
class LblDisplay extends JLabel {
IMediator med;
LblDisplay(IMediator
m) {
super("Just
start...");
med = m;
med.registerDisplay(this);
setFont(new Font("Arial",
Font.BOLD, 24));
}
}
class MediatorDemo extends JFrame implements ActionListener {
IMediator med = new
Mediator();
MediatorDemo() {
JPanel p = new
JPanel();
p.add(new
BtnView(this, med));
p.add(new BtnBook(this,
med));
p.add(new
BtnSearch(this, med));
getContentPane().add(new
LblDisplay(med), "North");
getContentPane().add(p,
"South");
setSize(400, 200);
setVisible(true);
}
public void
actionPerformed(ActionEvent ae) {
Command comd =
(Command) ae.getSource();
comd.execute();
}
public static void
main(String[] args) {
new
MediatorDemo();
}
}
El Mediator es comúnmente usado en el desarrollo de aplicaciones que poseen varios componentes dentro de las interfaces gráficas que poseen.
También aparece otra aplicación en el framework de dibujo Unidraw
Patrones relacionados
Un patrón muy parecido a éste es el Facade que se diferencia en que abstrae un sistema de objetos proporcionado una interfaz más conveniente, utilizando un protocolo unidireccional (Fachada realiza solo peticiones a las clases del subsistema pero no a la inversa), mientras que el Mediator usa un protocolo multidireccional.
Con el patrón Observer los objetos pueden comunicarse con el mediador.
Referencias
- Design Patterns Elements of Reusable Object-Oriented Software, GoF.
- http://dc.exa.unrc.edu.ar/nuevodc/materias/sistemas/2007/Patrones/1181918751/MediatorRes2.pdf
- http://kybele.escet.urjc.es/documentos/SI/Patrones/14_Mediator.ppt
No hay comentarios:
Publicar un comentario