miércoles, 30 de mayo de 2007

¿Qué es un puente (bridge) y cómo se debe utilizar?

El puente es el patrón más básico de todos y lo encontrará, en la medida que se familiarice más con los patrones, en general. Notará entonces, que el puente (en alguna forma) se encuentra en la cima de casi todos los otros patrones. Es por esto que se le conoce como la "madre" de los patrones de diseño.
¿Cómo puedo reconocer cuando necesito un puente?
La definición formal de un puente, tomada del Gof es:

"Desacoplar una abstracción de su implementación de tal forma que las dos puedan variar independientemente."

Espectacular, ¿eh? ¿Hacemos esto realmente en nuestro código? La respuesta corta es que probablemente nosotros lo hacemos más de lo que nos damos cuenta.

Vamos a tomar un ejemplo común en Visual Fox Pro.
Supongamos que nuestra aplicación necesita que le ingresen el nombre y apellido y que luego estos valores sean mostrados de alguna forma en otro lado.
Podríamos crear dos TextBox para ingresar estos datos y un EditBox para que estos sean mostrados.





Figura 1. Formulario


En el evento click del botón podríamos escribir el siguiente código:


ThisForm.txtMostrar.Value = ALLTRIM(thisform.txtApellido.Value) + ", " + ALLTRIM(thisform.txtNombre.Value)

Esto produce una salida donde el Apellido se muestra primero que el nombre y separados entre sí por una coma.
Ahora… si queremos reutilizar este código… IMPOSIBLE!.



¿Cuáles son los componentes de un puente?



Un puente tiene dos componentes esenciales, la "abstracción", que es el objeto responsable de inicializar una operación, y la "implementación", que es el objeto que la lleva a cabo. (Figura 2) La abstracción conoce su implementación porque guarda una referencia a la misma, o porque lo posee (por ejemplo, lo contiene). Observe que, a pesar de esta estructura, el diagrama denota que la abstracción crea la implementación, y que no es, en absoluto, un requerimiento del patrón. Un puente también puede hacer uso de una referencia ya existente para una misma implementación de objeto. De hecho, diseñar puentes de esta forma, puede ser muy eficiente porque diferentes objetos abstracción pueden ser utilizados en un mismo objeto implementación.








Figura 2. El patrón de puente básico

Debido a que Visual FoxPro tiene un modelo de contenedores muy bueno, la mayoría de los desarrolladores notarán que lo han utilizado (no intencionalmente) para implementar Puentes con más frecuencia de lo que imaginan. Sin embargo, no confunda el envío de mensajes con el puente. Si un método de un botón de comandos llama a un método en su formulario padre, esto implementa directamente la acción necesaria, que es enviar un mensaje, no un puente. Sin embargo, si el método del formulario va a llamar a otro objeto para que lleve a cabo la acción, entonces tenemos un puente.
Entonces, para implementar un puente necesita identificar qué objeto va a realizar la función de abstracción y cuál la implementación. Una vez que lo haya definido, todo lo que queda por decidir es cómo el puente entre los dos será codificado y esto dependerá enteramente del escenario.
¿Cómo implementar el puente en el caso anterior?

Para implementar el puente debemos separar la implementación de la abstracción. Para ello vamos a crear una clase de tipo Custom llamada puente dentro de alguna biblioteca de clases, para este caso será “ejemplos”. A la clase puente le vamos a anexar un método llamado “procesarNombre”. Este método recibirá como parámetros dos string y devolverá otro string. Quedaría algo como lo siguiente:

LPARAMETERS nombre,apellido
RETURN ALLTRIM(Apellido) + ", " + ALLTRIM(nombre)

Ahora bien, desde el formulario vamos a escribir el siguiente código:

MiPuente = CREATEOBJECT("Ejemplos.puente")
ThisForm.txtMostrar.Value=MiPuente.procesarnombres(thisform.txtNombre.Value,thisform.txtApellido.Value)

Como se puede observar la manera de cómo se procesan los nombres no le importan a mi aplicación. De hecho se puede cambiar la manera de procesar los nombres sin tocar nada de código en el formulario. Lo único que hay que respetar es la interfaz, que en este caso es el método procesarnombres().

Esta estrategia desacopla exitosamente la abstracción de la implementación y, como resultado, nuestro código, es mucho más reutilizable.

No hay comentarios.: