El patrón de diseño Mediator
Descripción
El patrón de diseño Mediator tiene como objetivo construir un objeto cuya vocación es encapsular las interacciones de un conjunto de objetos.
Ejemplo
El diseño de un sistema mediante objetos favorece la distribución del comportamiento entre estos objetos. No obstante, llevada al extremo, esta distribución puede llevar a tener un gran número de enlaces que obligan casi a cada objeto a conocer a todos los demás objetos del sistema. Un diseño con tal cantidad de enlaces puede volverse de pésima calidad porque supone un acoplamiento muy fuerte entre los objetos. Como cada objeto no puede trabajar sin los demás, el sistema se vuelve rápidamente monolítico, haciendo que cada vez sea más difícil mantenerlo y actualizarlo. Además para adaptar y modificar el comportamiento de una pequeña parte del sistema, resulta necesario definir numerosas subclases.
Las interfaces gráficas dinámicas son un buen ejemplo de un sistema de este tipo. Una modificación en el valor de un control gráfico puede conducir a modificar el aspecto de otros controles gráficos como, por ejemplo:
-
Volverse visible u oculto.
-
Modificar el número de valores posibles (para un menú).
-
Cambiar el formato de los valores que es necesario informar.
La primera posibilidad consiste en enlazar cada control con controles cuyo aspecto cambia en función de su valor. Tiene sus límites.
La otra posibilidad consiste en implementar el patrón de diseño Mediator. Éste consiste en construir...
Estructura
1. Diagrama de clases
La figura 22.3 detalla la estructura genérica del patrón de diseño Mediator.
Figura 22.3 - Estructura del patrón de diseño Mediator
2. Participantes
Los participantes del patrón de diseño Mediator son los siguientes:
-
Mediador define la interfaz del mediador para los objetos Elemento.
-
MediadorConcreto (Formulario) implementa la coordinación entre los elementos y gestiona las asociaciones con los elementos.
-
Elemento (AbstractControl) es la clase abstracta de los elementos que incluyen sus atributos, asociaciones y métodos comunes.
-
ElementoConcreto1 y ElementoConcreto2 (PopupMenu, ZonaInformacion y Boton) son las clases concretas de los elementos que se comunican con el mediador en lugar de con los demás elementos.
3. Colaboraciones
Los elementos envían y reciben mensajes a y del mediador. El mediador implementa la colaboración y la coordinación entre los elementos.
Dominios de aplicación
El patrón de diseño Mediator se utiliza en los casos siguientes:
-
Un sistema está formado por un conjunto de objetos basado en una comunicación compleja que conduce a asociar numerosos objetos entre ellos.
-
Los objetos de un sistema son difíciles de reutilizar puesto que poseen numerosas asociaciones con otros objetos.
-
La modularidad de un sistema es mediocre, obligando en los casos en los que se debe adaptar una parte del sistema a escribir numerosas subclases.
Ejemplo en PHP
A continuación proponemos simular la información de un formulario con la ayuda de entradas/salidas clásicas haciendo un bucle en una introducción secuencial de datos en cada control hasta que se valida el botón "OK" (mediante el teclado). Un menú permite elegir si el préstamo se realiza o no con un coprestatario.
El código fuente escrito en PHP de la clase AbstractControl se muestra a continuación.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Mediator;
abstract class AbstractControl
{
protected ?string $valor = null;
protected Formulario $director;
protected string $nombre;
public function __construct(string $nombre)
{
$this->nombre = $nombre;
}
public function getNombre(): string
{
return $this->nombre;
}
protected function setNombre(string $nombre): void
{
$this->nombre = $nombre;
}
protected function getDirector(): Formulario
{
return $this->director;
}
public function setDirector(Formulario $director): void
{
$this->director = $director;
}
public function getValor(): ?string
{
return $this->valor;
}
protected function setValor(string $valor): void
{
$this->valor = $valor;
}
protected function modifica(): void
{
$this->getDirector()->controlModificado($this); ...