El patrón de diseño Bridge
Descripción
El objetivo del patrón de diseño Bridge es separar una abstracción de su implementación para que ambas evolucionen de forma independiente.
Ejemplo
Para realizar la solicitud de matriculación de un vehículo de ocasión, conviene precisar sobre esta solicitud cierta información importante como el número de placa existente. El sistema muestra un formulario para solicitar esta información.
Existen dos implementaciones de los formularios:
-
Formularios HTML;
-
Formularios basados en widgets Qt.
Por tanto es posible introducir una clase abstracta FormularioMatriculacion y dos subclases concretas FormularioMatriculacionHtml y FormularioMatriculacionQt.
En una primera etapa, las solicitudes de matriculación solo afectan a España. A continuación, se hace necesario introducir una nueva subclase de FormularioMatriculacion correspondiente a las solicitudes de matriculación de Portugal, subclase llamada FormularioMatriculacionPortugal. Esta subclase debe a su vez ser abstracta y tener también dos subclases concretas por cada implementación. La figura 11.1 muestra el diagrama de clases correspondiente.
Figura 11.1 - Jerarquía de formularios integrando las subclases de implementación
Este diagrama pone de manifiesto dos problemas:
-
La jerarquía mezcla al mismo nivel implementaciones y abstracciones.
-
Los clientes son dependientes de las implementaciones y no de las abstracciones. En efecto, deben interactuar con clases concretas, lo que provoca un acoplamiento inoportuno.
Por lo tanto, la solución del patrón...
Estructura
1. Diagrama de clases
La figura 11.3 detalla la estructura genérica del patrón de diseño Bridge.
Figura 11.3 - Estructura del patrón de diseño Bridge
2. Participantes
Los participantes del patrón de diseño Bridge son los siguientes:
-
ClaseAbstracta (AbstractFormularioMatriculacion) es la clase abstracta que representa los objetos de dominio. Describe la interfaz para los clientes y contiene una referencia hacia un objeto que responde a la interfaz Implementación.
-
ClaseConcreta (FormularioMatriculacionEspana y FormularioMatriculacionPortugal) es la clase concreta que implementa los métodos de ClaseAbstracta.
-
Implementación (FormularioInterfaz) define la interfaz de las clases de implementación. Los métodos de esta interfaz no deben corresponder con los métodos de ClaseAbstracta. Ambos conjuntos de métodos son diferentes. La implementación incluye por lo general métodos de bajo nivel y los métodos de ClaseAbstracta son de alto nivel.
-
ImplementacionA, ImplementacionB (FormHtml, FormQt) son clases concretas que realizan los métodos incluidos en la interfaz Implementación.
3. Colaboraciones
Las operaciones de ClaseAbstracta y de sus subclases invocan a los métodos presentes en la interfaz Implementación.
Dominios de aplicación
El patrón de diseño Bridge se utiliza en los siguientes casos:
-
Para evitar que exista un vínculo demasiado fuerte entre la representación de los objetos y su implementación.
-
Para que los cambios en la implementación de los objetos no tengan impacto en las interacciones entre los objetos y sus clientes.
-
Para permitir a la representación de los objetos y a su implementación conservar su capacidad de extensión mediante la creación de nuevas subclases.
-
Para evitar obtener jerarquías de clases demasiado complejas como ilustra la figura 11.1.
Ejemplo en PHP
A continuación explicamos un ejemplo escrito en PHP basado en el diagrama de clases de la figura 11.2.
Comenzamos por la interfaz FormularioInterfaz que describe la implementación de los formularios. Esta interfaz contiene dos métodos, uno para visualizar un texto y otro para administrar una zona concreta.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Bridge;
interface FormularioInterfaz
{
public function dibujaTexto(string $texto): void;
public function administraZonaIndicada(): string;
}
Ahora nos interesamos por la clase de implementación FormHtml que simula la visualización y la introducción de un formulario HTML.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Bridge;
class FormHtml implements FormularioInterfaz
{
public function dibujaTexto(string $texto): void
{
echo "HTML: $texto" . PHP_EOL;
}
public function administraZonaIndicada(): string
{
$fp = fopen("php://stdin", 'r');
$line = rtrim(fgets($fp, 1024));
return $line;
}
}
A continuación se detalla la clase de implementación FormQt que simula la visualización y la introducción de un formulario basado en widgets Qt.
<?php
declare(strict_types=1);
namespace ENI\DesignPatterns\Bridge; ...