Você está na página 1de 20

PATRON BRIDGE

Objetivo del patrón

“Desacoplar una abstracción de su


implementación de manera que ambas
puedan cambiar independientemente.”
¿Cuando utilizarlo?
Lo que se busca es desacoplar completamente el
comportamiento de la Configuración de su final
implementación. Es más, se pretende poder
desarrollar y extender separadamente cada uno de
ellos sin que los cambios en uno afecten en el otro.

Esto se logra mediante la utilización del


patrón Bridge que permite tener dos jerarquías de
clases separadas que pueden extenderse en forma
independiente. Una define el comportamiento, lo
que se espera de una configuración. La otra define
la forma en que se implementa dicho
comportamiento.
¿Casos específicos?
Cuando:

 Se desea evitar un enlace permanente entre la abstracción y su


implementación. Esto puede ser debido a que la implementación
debe ser seleccionada o cambiada en tiempo de ejecución.
 Tanto las abstracciones como sus implementaciones deben ser
extensibles por medio de subclases. En este caso, el patrón
Bridge permite combinar abstracciones e implementaciones
diferentes y extenderlas independientemente.
 Cambios en la implementación de una abstracción no deben
impactar en los clientes, es decir, su código no debe tener que
ser recompilado.
 Se desea compartir una implementación entre múltiples objetos
(quizá usando contadores), y este hecho debe ser escondido a los
clientes.
ESTRUCTURA

Abstraction Implementador

operacion() operationImp()

RefinedAbstraction ConcreteImplA ConcreteImplB

operationImp() operationImp()
participantes
 Abstraction :
• define una interface abstracta. Mantiene una referencia a un objeto de tipo
Implementor.

 RefinedAbstraction:
• extiende la interface definida por Abstraction

 Implementor :
• define la interface para la implementación de clases. Esta interface no se tiene que
corresponder exactamente con la interface de Abstraction; de hecho, las dos interfaces
pueden ser bastante diferente. Típicamente la interface Implementor provee sólo
operaciones primitivas, y Abstraction define operaciones de alto nivel basadas en estas
primitivas.

 ConcreteImplementor :
• implementa la interface de Implementor y define su implementación concreta.

 colaboración:
• Abstraction redirige las peticiones de los clientes a su objeto implementor
EJEMPLO: dibujar un rectangulo
classRectangulo
{
publicvoiddibujar()
{
dibujar_linea(x1, y1, x2, y1);
dibujar_linea(x2, y1, x2, y2);
dibujar_linea(x2, y2, x1, y2);
dibujar_linea(x1, y2, x1, y1);
}
Abstractprotected voiddibujar_linea( doublex1, doubley1, doublex2, doubley2);
}

classV1RectanguloextendsRectangulo
{
dibujar_linea( doublex1, doubley1, doublex2, doubley2)
{
PD1.DrawLine( x1, y1, x2, y2);
}
}

classV2RectanguloextendsRectangulo
{
dibujar_linea( doublex1, doubley1, doublex2, doubley2)
{
PD2.DibujarLinea( x1, x2, y1, y2);
}
}
Y si queremos dibujar además un
circulo??
abstractclassForma
{
abstractpublicvoiddibujar();
}
abstractclassRectanguloextendsForma
{
publicvoiddibujar() {... }
abstractprotectedvoiddibujar_linea();
}
classV1RectanguloextendsRectangulo
{
....
}
classV2RectanguloextendsRectangulo
{
....
}
abstractclassCirculo extendsForma
{
publicvoiddibujar() {dibujar_circulo( x,y,r);}
abstractprotectedvoiddibujar_circulo( double x, double y, double r);
}
classV1CirculoextendsCirculo
{
protectedvoiddibujar_circulo() {PD1.DrawCircle(x, y, r);}
}
classV2CirculoextendsCirculo
{
protectedvoiddibujar_circulo() { PD2.DibujarCirculo(x, y, r);}
}
PERO ... TENDRIAMOS UN
PROBLEMA??...

• Tendríamos 4 formas >> v1Rectangulo,


v2rectangulo, v1circulo, v2circulo ; una
explosión combinatoria de clases.
• Si pusiéramos otro método de dibujo (un pd3)
tendríamos 6 formas ...
Posible solución al problema ...
Aplicaremos un bridge
• Teniendo en cuenta que tenemos una
abstracción con diferentes
implementaciones...
Consecuencias
Desacoplamiento entre interfaz e
• Separaremos las abstracciones de las
implementación
implementaciones, para que cada una sea
Más facilidad para extender el sistema
Esconde los detalles de la implementación
independiente.

• generaríamos entonces , si es necesario,


una nueva clase, la del bridge.
ESTA SERÍA LA MEJOR SOLUCION
aplicabilidad
• LO QUE QUEREMOS ES DESLIGAR
PERMANENTEMENTE LA ABSTRACCION DE SU
IMPLEMENTACION.
• Con esto hacemos que sea fácil extender
a las abstracciones y sus
implementaciones mediante subclases.
• Logramos entonces, además, que los
posibles cambios que hayan en las
clases, sean imperceptibles al cliente.
El código finalizado
publicclassCliente
{
publicstaticvoidmain(Stringargv[])
{
Forma r1, r2;
Dibujadordp;
dp= newV1Dibujador();
r1= newRectangulo(dp,1,1,2,2);
dp= newV2Dibujador();
r2=newCirculo(dp, 2,2,3);
r1.dibujar();
r2.dibujar();
}
}
abstractclassForma
{
abstractpublicdibujar();
privateDibujador_dp;
Forma (dibujadordp)
{
_dp=dp;
}
protectedvoiddibujar_linea(doublex1, doubley1, doublex2, doubley2)
{
_dp.dibujar_linea(x1, y1, x2, y2);
}
protectedvoiddibujar_circulo (doublex, doubley, doubler)
{
_dp.dibujar_circulo (x, y, r);
}
}
abstractclassDibujador
{
abstractpublicvoiddibujar_linea(doublex1, doubley1, doublex2, doubley2);
abstractpublicvoiddibujar_circulo (doublex, doubley, doubler);
}
classV1DibujadorextendsDibujador
{
publicvoiddibujar_linea(doublex1, doubley1, doublex2, doubley2)
{
PD1.DrawLine(x1, y1, x2, y2);
}
publicvoiddibujar_circulo (doublex, doubley, doubler)
{
PD1.DrawCircle(x, y, r);
}
}
classV2DibujadorextendsDibujador
{
publicvoiddibujar_linea(doublex1, doubley1, doublex2, doubley2)
{
PD2.DibujarLinea(x1, x2, y1, y2);
}
public void dibujar_circulo (doublex, doubley, doubler)
{
PD2.DibujarCirculo(x, y, r);
}
}
classRectanguloextendsForma
{
privatedouble_x1, _x2, _y1, _y2;
publicRectangulo(Dibujadordp, doublex1, doublex2, doubley1, doubley2)
{
super(dp); _x1=x1; _x2=x2; _y1=y1; _y2=y2;
}
publicvoiddibujar ()
{
dibujar_linea(_x1, _y1, _x2, _y1);
dibujar_linea(_x2, _y1, _x2, _y2);
dibujar_linea(_x2, _y2, _x1, _y2);
dibujar_linea(_x1, _y2, _x1, _y1);
}
}
classCirculo extendsForma
{
privatedouble_x, _y, _r;
publicCirculo (Dibujadordp, doublex, doubley, doubler)
{
super(dp); _x=x; _y=y; _r=r;
}
publicvoiddibujar ()
{
dibujar_circulo (_x, _y, _r);
}
}
// Implementaciones de PD1 y PD2
classPD1
{
staticpublicvoidDrawLine(doublex1, doubley1, doublex2, doubley2)
{
// Implementación
}
staticpublicvoidDrawCircle(doublex, doubley, doubler)
{
// Implementación
}
}
classPD2
{
staticpublicvoidDibujarLinea(doublex1, doublex2, doubley1, doubley2)
{
// Implementación
}
staticpublicvoidDibujarCirculo(doublex, doubley, doubler)
{
// Implementación
}
}
Gracias!

Você também pode gostar