domingo, 17 de mayo de 2009

BRIDGE

Nombre

Bridge.

También Conocido

Handle / Body

Clasificación

Estructural.

Intención


Desacopla la abstracción de su implementación permitiendo que las dos varíen independientemente.

Motivo

Cuando una abstracción puede tener varias im-plementaciones posibles el camino habitual para acomodarlas es usar herencia. Una clase abstracta define la interfaz y clases concretas la implementa de diferentes formas. El problema es que esta solución no es lo suficientemente flexible. La herencia ata una implementación a la abstracción permanentemente, lo que hace la hace difícil de modificar, extender y rehusar la implementación y la abstracción independientemente. La respuesta a esta flexibilidad esta en utilizar el patrón de diseño bridge.

Aplicabilidad

Bridge debe ser usado cuando:
  • Quiere evitar un enlace permanente entre la abstracción y su implementación.

  • Tanto la abstracción como su implementación deben ser extensibles por subclases. El patrón de diseño bridge deja combinar la implementación y su abstracción y permite extenderlas independientemente.

  • Cambios en la implementación de una abs-tracción no deben tener impacto sobre el cliente.
  • La herencia puede generar una explosión de clases cuando queremos dividir un objetos; bridge evita dicha explosión.

  • Se quiere partir la implementación de una abstracción en múltiples objetos, que deben estar ocultas al cliente.

Estructura




Participantes

  • Abstraction: Define la interfaz de la abstracción. Mantiene una referencia a un objeto del tipo implementor.

  • RefinedAbstraction: Extiende la interfaz definida por Abstraction.
  • Implementor: Define una interfaz para la implementación de clases; ésta interfaz no tiene una correspondencia directa a la interfaz de la abstracción, de hecho pueden ser muy diferentes. Por lo general implementor define operaciones primitivas, mientras que abstraction define operaciones de más alto nivel basadas en las de implementor.
  • ConcrteImplementor: implementa la interfaz implementor definiendo una implementación concreta.

Colaboración


Abstraction envía las peticiones del cliente a su objeto implementor.

Consecuencias

Las siguientes son consecuencias del uso del patrón Bridge:
  • Desacopla la abstracción de su implementación. La abstracción no está permanentemente ligada a la implementación. La implementación puede ser configurada en tiempo de ejecución. Así mismo elimina dependencias en la compilación; es decir, cambios en una implementación, no requiere recompilación de la abstracción y su cliente.
  • Provee extensibilidad. La abstracción y la implementación pueden tener subclases independientemente.
  • Oculta detalles de implementación a los clientes.

Implementación

Se deben considerar las siguientes situaciones cuando se aplica el patrón bridge:

  • Solo un implementador. Cuando sólo hay una implementación, no es necesario crear una clase abstracta implementor. Sin embrago se puede hacer para mantener al cliente independiente de cambios en la implementación.
  • Crear la implementación correcta. Si la abstracción conoce todas las implementaciones concretas, luego ésta puede instanciar una en su constructor, se decide entre las implementaciones, pasando un parámetro en el constructor. La forma en que se toma la decisión depende de las características de la implementación.

Código ejemplo


El código ejemplo se basa en la abstracción de una operación sencilla, de dos números, las implementaciones son sumar, multiplicar y dividir.


//esta es la interfaz de la implementacion (implementor)

public interface Implementor {

public int operacion(int a, int b);

}

//esta es una implementación concreta (concretImplementor)

public class Sumar implements Implementor {

public int operacion(int a, int b) {

return a+b;

}

}

//esta es una implementación concreta (concretImplementor)

public class Multiplicar implements Implementor {

public int operacion(int a, int b) {

return a*b;

}

}

// esta es una implementación concreta (concretImplementor)

public class Dividir implements Implementor {

public int operacion(int a, int b) {

return a/b;

}

}

//esta es la interfaz de la abstraccion (abstraction)

public interface Abstraction {

public int operar(int num1, int num2);

}

//esta clase esxtiende la interfaz definida por abstraction (RedefinedAbstraction)

import operacion.Implementor;

public class RefinedAbstraction implements Abstraction {

Implementor implementacion=null;

public RefinedAbstraction(Implementor imp){

this.implementacion=imp;

}

public int operar(int num1, int num2) {

return implementacion.operacion(num1,num2);

}

}

//Es la clase cliente que utiliza la abstraccion (Client)

import operacion.Implementor;

import operacion.Abstraction;

public class Cliente {

public static void main(String[] args) {

int num1=4;

int num2=2;

Implementor [] imp= {new Sumar(),new Multiplicar(), new Dividir()};

Abstraction abst[] ={ new RefinedAbstraction(imp[0]), new RefinedAbstraction(imp[1]), new RefinedAbstraction(imp[2])};

for (int i=0; i<3;i++){

System.out.println(abst[i].operar(num1, num2));

}

}

}


Usos conocidos

  • En ET++, se usa para la abstracción del tipo de ventana.
  • Next’s AppKit usa el patrón en la implementación y representación de imágenes gráficas.

Patrones relacionados

  • Abstract factory puede crear y configurar un, bridge en particular.
  • Adapter tiene una estructura similar pero su intención es diferente. El patrón bridge separa la abstracción de la implementación de un componente, permitiendo que sean modificados independientemente, mientras adapter reutiliza un componente ya existente que no es compatible.


Referencias bibliográficas

[1] Erich Gamma et al, Elements of reusable object-oriented software.

[2] Steve Holzner, Design patterns for dummies, Wiley Publishing Inc, Indianapolis, EEUU, 2006, 339.

[3] Jesús García Molina, Análisis y diseño de software - Patrones de diseño, dis.um.es/~jmolina/astema3.


1 comentario:

FELIPE dijo...

Como se puede hacer el patron de diseño Bridge con c# en asp.net.
Gracias.