Patron+Bridge

20
PATRON BRIDGE

Transcript of Patron+Bridge

Page 1: Patron+Bridge

PATRON BRIDGE

Page 2: Patron+Bridge

Objetivo del patrón

“Desacoplar una abstracción de su implementación de manera que ambas puedan cambiar independientemente.”

Page 3: Patron+Bridge

¿Cuando utilizarlo?

Lo que se busca es desacoplar completamente elcomportamiento de la Configuración de su finalimplementación. Es más, se pretende poderdesarrollar y extender separadamente cada uno deellos sin que los cambios en uno afecten en el otro.

Esto se logra mediante la utilización delpatrón Bridge que permite tener dos jerarquías declases separadas que pueden extenderse en formaindependiente. Una define el comportamiento, loque se espera de una configuración. La otra definela forma en que se implementa dichocomportamiento.

Page 4: Patron+Bridge

¿Casos específicos?

Cuando:

Se desea evitar un enlace permanente entre la abstracción y suimplementación. Esto puede ser debido a que la implementacióndebe ser seleccionada o cambiada en tiempo de ejecución.

Tanto las abstracciones como sus implementaciones deben serextensibles por medio de subclases. En este caso, el patrónBridge permite combinar abstracciones e implementacionesdiferentes y extenderlas independientemente.

Cambios en la implementación de una abstracción no debenimpactar en los clientes, es decir, su código no debe tener queser recompilado.

Se desea compartir una implementación entre múltiples objetos(quizá usando contadores), y este hecho debe ser escondido a losclientes.

Page 5: Patron+Bridge

ESTRUCTURA

Implementador

ConcreteImplA

operationImp()

operationImp()

ConcreteImplB

operationImp()

Abstraction

operacion()

RefinedAbstraction

Abstraction

operacion()

Page 6: Patron+Bridge

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

Page 7: Patron+Bridge

EJEMPLO: dibujar un rectangulo

Page 8: Patron+Bridge

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);}

}

Page 9: Patron+Bridge

Y si queremos dibujar además un circulo??

Page 10: Patron+Bridge

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);}}

Page 11: Patron+Bridge

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 ...

Page 12: Patron+Bridge

Posible solución al problema ...

Page 13: Patron+Bridge

Aplicaremos un bridge

ConsecuenciasDesacoplamiento entre interfaz e implementaciónMás facilidad para extender el sistemaEsconde los detalles de la implementación

• Teniendo en cuenta que tenemos una abstracción con diferentes implementaciones...

• Separaremos las abstracciones de las implementaciones, para que cada una sea independiente.

• generaríamos entonces , si es necesario, una nueva clase, la del bridge.

Page 14: Patron+Bridge

ESTA SERÍA LA MEJOR SOLUCION

Page 15: Patron+Bridge

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.

Page 16: Patron+Bridge

El código finalizadopublicclassCliente{

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); }

}

Page 17: Patron+Bridge

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); }

}

Page 18: Patron+Bridge

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); }

}

Page 19: Patron+Bridge

// Implementaciones de PD1 y PD2classPD1 {

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}

}

Page 20: Patron+Bridge

Gracias!