Clasificación:
Patrón
Estructural.
Propósito:
Separa abstracción e implementación, así ambas pueden
variar de forma independiente. A diferencia del patrón Adapter, considera
como las interfaces son implementadas, en este sentido asocia abstracción y sus
potenciales implementaciones. Suele aplicarse al empezar un diseño,
para permitir que las abstracciones e implementaciones evolucionen
independientemente.
También Conocido como:
Puente / Cuerpo.
Intención:
Desacopla una abstracción de su implementación de
modo que ambos puedan cambiar independientemente.
Motivacion:
La herencia permite que una abstracción tenga
varias implementaciones: esta relación se define en tiempo de
compilación. Una clase abstracta define la interfaz a la
abstracción y la aplicación de las subclases concretas en
diferentes maneras. Sin embargo, no siempre es lo
suficientemente flexible, obligando a una aplicación de herencia
para la captación permanente, por lo que resulta difícil de modificar, ampliar,
y la reutilización de abstracciones e implementaciones independiente.
Aplicabilidad:
Se utiliza el patrón cuandose desea evitar una
permanente vinculacion entre una abstracción y su aplicación. Este
podría ser el caso, por ejemplo, cuando la aplicación debe seleccionar
o cambiar en tiempo de ejecución. Tanto las abstracciones y sus
implementaciones deben ser extensibles por las subclases. En este caso, el
patrón de Bridge permite combinar las diferentes abstracciones e
implementaciones y ampliar de forma independiente-, de modo que los cambios en
las clases abstractas existentes no deben influir en la aplicación , tal modo
se comparte una implementación entre múltiples objetos, sin que lo
noten los clientes.
Estructura:
La estructura de un Bridge se puede clasificar en
dos partes: la parte abstracta y la implementacion de la interfaz
por las diferentes clases del grupo de objetos, de modos que la
relación se hace mediante una agregacion de la interfaz por partde de la clase
abstracta, de esta forma se relaciona la primer parte y la segunda, donde sus
comportamientos son independientes.
Los participantes:
Abstraction:
- Define la abstracción de la interfaz, manteniedo una referencia a un objeto que implementa la interfaz.
RefinedAbstraction:
- Amplía la interfaz definida por la abstracción, de modo que captura las especificaciones o información necesaria proveniente del objeto que implementa la interfaz.
Implementor:
- Define la interfaz de la aplicación clases. Esta interfaz no tiene que corresponder exactamente a la interfaz de abstracción, de hecho las dos interfaces pueden ser muy diferentes. Normalmente la interfaz Implementor proporciona sólo operaciones primitivas, y define la abstracción de alto nivel sobre la base de estas operaciones primitivas.
ConcreteImplementor:
- Implementa la interfaz concreta y define sus aplicació
Client:
- Utiliza los objetos proporcianados por sus gusto.
Colaboraciones:
Abstracción
remite las solicitudes de los clientes a su ejecutor objeto, desacoplando
la interfaz e implementación. así ésta no se vincula
permanentemente a la interfaz, y se puede determinar en tiempo de
ejecución (incluso cambiar). – Se eliminan dependencias de compilación,
consiguiendo una arquitectura más estructurada en niveles mejorando la
extensibilidad donde las jerarquías de abstracción y de implementación pueden
evolucionar independientemente.
Consecuencias:
- La disocia la interfaz de la aplicación. Una aplicación no está vinculada permanente a una interfaz. Es incluso posible que un objeto pueda cambiar su aplicación en tiempo de ejecución. La Abstracción y la interfaz eliminan tiempo de compilación y dependencias de la aplicación, de modo que el cambio de una clase no requiere recompilar la clase de abstracción y de sus clientes. Esta propiedad es esencial cuando se debe garantizar la compatibilidad binaria entre diferentes versiones de una biblioteca de clases. Por otra parte, esta disociación alienta capas que pueden conducir a una mejor sistema estructurado.
- Mejora de la extensibilidad, de forma que se puede ampliar la Abstracción y ejecutor en jerarquías independientes.
- Oculta detalles de implementación a los clientes, protegiendo detalles de implementación, como el intercambio de objetos y el mecanismo de acompañamiento de referencias (en su caso).
Implementación:
En el
siguiente ejemplo, se lleva a cavo la solicitud de un pedido en una panadería,
donde el cliente elige el diferente tipo de pan que hay disponible.
//nuestra
clase Abstraction, su método permite obtener el tipo de pan del pedido//
package Logica;
public abstract
class Panaderia {
public abstract
TipoDePan getImplementador();
public abstract
String nombrePan();
}
//*Ahora creamos una clase que hereda de Panaderia, en
la cual se estructura el metodo de la clase abstracta y se crean nuevos
metodos, los cuales trabajan con un objeto de la que implementa la interfaz*//
package
Logica;
public class
Panes extends Panaderia {
private TipoDePan pan;
public String nombrePan() {
return pan.tipoPan();
}
public void setInterfaz(TipoDePan
tipoInterfaz) {
pan = tipoInterfaz;
}
public TipoDePan getImplementador() {
return pan;
}
}
// Creamos
la interfaz//
package
Logica;
public
interface TipoDePan {
public abstract String tipoPan();
}
//*Ahora se
crean las clases de los diferentes tipos de pan disponibles sobreescribiendo el
método implementado de la interfaz*//
package
Logica;
public class
PanDeFrutas implements TipoDePan {
public String tipoPan() {
return "Pan de Frutas";
}
}
package
Logica;
public class
PanIntegral implements TipoDePan {
public String tipoPan() {
return "Pan integral";
}
}
package
Logica;
public class
PanLight implements TipoDePan {
public String tipoPan() {
return "Pan Light";
}
}
Por último
tenemos la vantana donde el cliente podra seleccionar y obtener su pedido:
package
Interfaz;
import
Logica.*;
import
java.awt.event.ActionEvent;
import
java.awt.event.ActionListener;
import
javax.swing.JButton;
import
javax.swing.JFrame;
import
javax.swing.JLabel;
public class
Pedido extends JFrame implements ActionListener {
//atributos
de la clase//
Panaderia panaderia ;
private JButton panIntegral;
private JButton panLight;
private JButton panDeFrutas;
private JLabel suOrden;
//constructor de la clase, e inicializamos y
ubicamos los atributos//
public Pedido(){
this.setSize(400,300);
this.setLayout(null);
this.setDefaultCloseOperation(Pedido.DISPOSE_ON_CLOSE);
this.setTitle(":::Panaderia:::");
suOrden = new JLabel();
suOrden.setSize(300,100);
suOrden.setLocation(30, 20);
suOrden.setText("Seleccione su Pan
:");
this.getContentPane().add(suOrden);
panIntegral = new JButton();
panIntegral.setSize(110, 30);
panIntegral.setLocation(10, 100);
panIntegral.setText("pan Integral");
this.getContentPane().add(panIntegral);
panIntegral.addActionListener(this);
panLight = new JButton();
panLight.setSize(110, 30);
panLight.setLocation(130, 100);
panLight.setText("pan Light");
this.getContentPane().add(panLight);
panLight.addActionListener(this);
panDeFrutas = new JButton();
panDeFrutas.setSize(120, 30);
panDeFrutas.setLocation(250, 100);
panDeFrutas.setText("pan De Frutas");
this.getContentPane().add(panDeFrutas);
panDeFrutas.addActionListener(this);
}
//manupula el objeto segun la especificacion
del cliente//
@Override
public void actionPerformed(ActionEvent e) {
//inicializa
un objeto de la clase Panes//
Panes pan= new Panes();
if (e.getSource() == panDeFrutas) {
//reliza la
implemntacion pasando en su método el tipo de pan que se eligió//
pan.setInterfaz(new PanDeFrutas());
}
if (e.getSource() == panLight) {
pan.setInterfaz(new PanLight());
}
if (e.getSource() == panIntegral) {
pan.setInterfaz(new PanIntegral());
}
//se
presenta al cliente el pedido como tal//
suOrden.setLocation(100, 130);
suOrden.setText("Su orden es : " +
pan.nombrePan());
}
}
Usos
conocidos:
Las clases
Button y MenuItem
de Java
facilitan la utilización de este patrón, declaran los métodos getActionCommand
y setActionCommand para dar nombres a las acciones realizadas por los objetos,
facilitándose una correspondencia entre ambos.
Patrones
Relacionados:
- Abstract Factory permite crear y configurar un Bridge particular (y esta factoría puede ser un Singleton).
- El patrón Adaptador tiene también el objetivo de hacer trabajar juntas clases con distinta interfaz, pero en general se aplica a sistemas que ya existen. El patrón Bridge suele aplicarse al empezar un diseño, para permitir que las abstracciones e implementaciones evolucionen independientemente.
Referencias:
PDF-Departamento
de Sistemas Informáticos y Programación Curso de doctorado 1999
-2000 Patrones de diseño orientado
a objetos.
DesIgn Patterns: Elements of Reusable
Object-Oriented Software Gamma, Helm, Johnson, Vlissides Editorial Addison-Wesley.
No hay comentarios:
Publicar un comentario