No entiendo el patrón de diseño "puente" en absoluto. He visitado varios sitios web, pero no me han ayudado.
¿Alguien puede ayudarme a entender esto?
No entiendo el patrón de diseño "puente" en absoluto. He visitado varios sitios web, pero no me han ayudado.
¿Alguien puede ayudarme a entender esto?
Respuestas:
En OOP usamos polimorfismo para que una abstracción pueda tener múltiples implementaciones. Veamos el siguiente ejemplo:
Se introdujo un nuevo requisito y debe incorporar la perspectiva de aceleración de los trenes, por lo tanto, cambie el código como se muestra a continuación.
El código anterior no es mantenible y carece de reutilización (suponiendo que podamos reutilizar el mecanismo de aceleración para la misma plataforma de seguimiento). El siguiente código aplica el patrón del puente y separa las dos abstracciones diferentes, el transporte del tren y la aceleración .
fuente
Monorail
ya que no son realmente dos palabras, es una sola palabra (compuesta). Un MonoRail sería una subclase de Rail en lugar de un tipo diferente de rail (que es). Al igual que noSunShine
CupCake
Sunshine
Cupcake
Si bien la mayoría de los patrones de diseño tienen nombres útiles, considero que el nombre "Puente" no es intuitivo con respecto a lo que hace.
Conceptualmente, inserta los detalles de implementación utilizados por una jerarquía de clases en otro objeto, generalmente con su propia jerarquía. Al hacerlo, está eliminando una dependencia estrecha de esos detalles de implementación y permitiendo que los detalles de esa implementación cambien.
En pequeña escala, comparo esto con el uso de un patrón de estrategia en la forma en que puede conectar un nuevo comportamiento. Pero en lugar de simplemente envolver un algoritmo como se ve a menudo en una estrategia, el objeto de implementación generalmente está más lleno de funciones. Y cuando aplica el concepto a toda una jerarquía de clases, el patrón más grande se convierte en un Puente. (De nuevo, odio el nombre).
No es un patrón que usará todos los días, pero lo he encontrado útil al manejar una explosión potencial de clases que puede ocurrir cuando tiene una (aparente) necesidad de herencia múltiple.
Aquí hay un ejemplo del mundo real:
Tengo una herramienta RAD que le permite colocar y configurar controles en una superficie de diseño, por lo que tengo un modelo de objetos como este:
Y así sucesivamente, con quizás una docena de controles.
Pero luego se agrega un nuevo requisito para admitir múltiples temas (look-n-feel). Digamos que tenemos los siguientes temas:
Win32
,WinCE
,WinPPC
,WinMo50
,WinMo65
. Cada tema tendría diferentes valores o implementaciones para operaciones relacionadas con la representación como DefaultFont, DefaultBackColor, BorderWidth, DrawFrame, DrawScrollThumb, etc.Podría crear un modelo de objeto como este:
etc., para un tipo de control
etc., para cada tipo de control (de nuevo)
Se entiende la idea: se obtiene una explosión de clase del número de widgets por el número de temas. Esto complica al diseñador de RAD haciéndolo consciente de todos y cada uno de los temas. Además, agregar nuevos temas obliga a modificar el diseñador RAD. Además, hay mucha implementación común dentro de un tema que sería genial heredar, pero los controles ya están heredando de una base común (
Widget
).Entonces, en cambio, lo que hice fue crear una jerarquía de objetos separada que implementa el tema. Cada widget contendría una referencia al objeto que implementa las operaciones de representación. En muchos textos, esta clase tiene el sufijo de una
Impl
pero me desvié de esa convención de nomenclatura.Así que ahora mi
TextboxWidget
aspecto es el siguiente:Y puedo hacer que mis diversos pintores hereden mi base de temas específicos, lo que no podía hacer antes:
Una de las cosas buenas es que puedo cargar dinámicamente las implementaciones en tiempo de ejecución, lo que me permite agregar tantos temas como quiera sin cambiar el software principal. En otras palabras, mi "implementación puede variar independientemente de la abstracción".
fuente
Win32TextboxPainter
yWin32ListPainter
de dónde proveníaWin32WidgetPainter
. Usted puede tener un árbol de herencia en el lado de la aplicación, pero debe ser más genérico (tal vezStaticStyleControlPainter
,EditStyleControlPainter
yButtonStyleControlPainter
) con las operaciones primitivas necesarias anulado, según sea necesario. Esto está más cerca del código real en el que estaba basando el ejemplo.El puente tiene la intención de desacoplar una abstracción de su implementación concreta , de modo que ambos puedan variar independientemente:
El puente logra esto usando la composición:
Observaciones adicionales sobre una confusión frecuente
Este patrón es muy similar al patrón adaptador: la abstracción ofrece una interfaz diferente para una implementación y utiliza la composición para hacerlo. Pero:
En este excelente libro seminal sobre patrones de diseño, los autores también observan que:
fuente