¿Cuáles son las ventajas del patrón delegado sobre el patrón observador?


9

En el patrón de delegado , solo un objeto puede escuchar directamente los eventos de otro objeto. En el patrón de observación , cualquier número de objetos puede escuchar los eventos de un objeto en particular. Al diseñar una clase que necesita notificar a otro (s) objeto (s) de eventos, ¿por qué usaría el patrón delegado sobre el patrón observador? Veo el patrón de observador como más flexible. Es posible que ahora solo tenga un observador, pero un diseño futuro puede requerir múltiples observadores.


44
¿Qué quiere decir con "patrón de delegado"? Si está hablando de algo como los delegados de .net, puede tener tantos suscriptores como desee.
CodesInChaos

Relacionado, aunque más centrado en el cacao: NSNotificationCenter vs delegación (utilizando protocolos)?
Mouviciel

Respuestas:


7

No hay un patrón de delegado per se. Voy a suponer que te refieres al patrón de delegación .

Según tengo entendido, son el reverso completo el uno del otro y se utilizan para diferentes propósitos.

Generalmente, con un patrón de observador , cualquier número de objetos de observador escuchará un evento en un segundo objeto y actuará en el evento. El segundo objeto no tiene conocimiento de sus oyentes. Simplemente los llama.

Se pasa un objeto delegado al segundo objeto que llama a métodos directamente en el delegado. Y ahí radica la ventaja que estás buscando. En lugar de enviar un solo mensaje a múltiples oyentes, tiene control completo sobre un solo objeto (en un momento dado). Ver también Inversión de control .


6

Estás mirando las cosas incorrectamente. Un observador ve que ocurre un evento particular. No lo impacta, ni lo posee. Un delegado maneja un evento en particular y tiene la propiedad del controlador, incluso si el delegador posee la interfaz para el evento.


1
Un delegado realmente no es más que un observador de un evento. Un delegado no necesita "manejar" nada. No puede hacer nada de forma segura y no afectará (o al menos no debería) afectar la instancia que desencadenó el evento.
Marjan Venema

55
@MarjanVenema: si el objeto A no delega la responsabilidad del evento en el objeto B, no está utilizando el patrón de delegación: está utilizando el patrón de observador con un solo observador.
Telastyn

Sí, eso es lo que estaba pensando. Entendí que delegado son los tipos de firma de evento que usará el suscriptor de un evento "OnWhatever". Aparentemente, los delegados en C # no son suscriptores únicos, como lo son, por ejemplo, en Delphi.
Marjan Venema

@Marjan Venema "Un delegado realmente no es más que un observador de un evento". - Depende de qué idioma estás hablando. En el Objetivo C, algunos delegados son responsables de proporcionar datos, por ejemplo, delegados de datos, y un objeto al que le falta un delegado de datos no tiene datos para presentar. En esos casos, está ocurriendo una delegación, distinta del acto de simplemente observar algo.
oculto

1
@occulus: gracias por la aclaración. Lástima que los idiomas no puedan ponerse de acuerdo sobre la terminología ... Hablar sobre la programación de una manera agnóstica del lenguaje se vuelve un poco difícil cuando las personas entienden diferentes cosas para las mismas palabras.
Marjan Venema

4

Esa es una cuestión de varias compensaciones.

Compensaciones:

  • flexibilidad (en términos de tener n> 1 delegados / observadores)
  • costo de enviar un mensaje
  • resiliencia (capacidad de mantener la falta de disponibilidad de delegados / observadores)
  • facilidad de uso

Patrón delegado:

  • no es muy flexible: no es posible agregar más de 1 delegado (implica alguna forma de "delegado múltiple", es decir, patrón de observador)
  • enviar un mensaje es barato, O (1): el mismo costo que llamar a cualquier otra función o método (no se requiere búsqueda, cola de mensajes u otra infraestructura)
  • generalmente no es resistente: se espera que los delegados estén presentes y hagan su parte del trabajo, es decir, el remitente tiende a fallar si no se conoce al delegado
  • fácil de entender, fácil de implementar

Patrón de observador:

  • muy flexible: se espera agregar n> 1 observadores por diseño
  • enviar un mensaje tiene un costo implícito por el número de observadores, O (n), es decir, n observadores toman n tiempo y mensajes (al menos en una implementación ingenua)
  • generalmente resistente: generalmente no se espera que los observadores realicen ningún trabajo por parte del remitente. Es decir, incluso si no hay observador, el remitente no se ve afectado
  • puede volverse bastante complejo de comprender, en particular, se espera que los observadores reaccionen a los mensajes (¿importa el orden ?, ¿qué observador responde de qué manera?)

1

El patrón de delegado, según tengo entendido, se conoce como el mecanismo de controlador de eventos en otros idiomas, por ejemplo, Delphi. Como tal, simplemente es una implementación del patrón de observador con una restricción importante: solo un oyente a la vez.

La desventaja de los controladores de eventos o delegados es obvia: solo un observador.

La ventaja no es tan obvia: el rendimiento. Con un patrón de observador puede agregar muchos observadores. Cuando se produce un evento sobre el que se debe notificar a los observadores, deberá enumerarlos y enviar una notificación a cada uno. Esto puede atascar rápidamente cualquier instancia observada, especialmente cuando el número de eventos que requieren notificación también es significativo.


¿Eh? El delegado de C # es solo la firma de un método como un tipo de variable (equivalente a, por ejemplo, int (*my_int_f)(int)en C). Siempre pensé que lo habrían hecho más fácil de entender al hacerlo funcionar más como struct / enum. Un evento es un enlace para una variedad flexible de oyentes, que utiliza una sola firma de delegado. Usted podría hacerlo sin un evento (por lo que supongo que la OP significaba patrón de Delegación, que es muy diferente), pero el lenguaje está haciendo más fácil para usted.
pdr

hmm No tan bien versado en C # todavía. Entendí que los delegados son el equivalente de los tipos de firma de eventos utilizados por los eventos "OnWhatever" en Delphi, por ejemplo. Entonces, ¿los eventos de C # pueden ser suscritos por múltiples oyentes?
Marjan Venema

La acción genérica <T> es un delegado. No tiene nada que ver con los eventos, es una variable que se pasa. Y sí, varios oyentes pueden escuchar un evento.
pdr

ok gracias, espero poder mantenerlo claro ... :-) Tomó la referencia de C # y se enfocó más en el mecanismo del evento.
Marjan Venema

1

Esta es una publicación antigua, pero de todos modos voy a intervenir porque las otras respuestas no tratan con lo que sucede cuando se usa cualquiera de los patrones, parecen estar más relacionados con la teoría que con la práctica.

Cómo funcionan la delegación y el observador

Con Delegación, el delegador elige exactamente quién responderá a un evento en particular en el momento en que se crea la fuente del evento potencial. Se podría pensar en este oyente como un solo observador . En el caso del patrón Observador, el observador elige a quién está observando cuando lo desea; así que las dependencias se invierten cuando se trata de observador frente a delegación. Con el patrón de observador, piense en un periódico y suscriptores como observadores. Los observadores tienen el control de cuándo se crea la relación. Con delegación piense en un empleado y un empleador. El empleador tiene el control de cuándo se crea la relación y exactamente quién está a cargo de eventos específicos. Los empleados no pueden elegir en qué tareas están trabajando ... en general.

Algunos argumentan que la delegación puede tener un observador, pero creo que la verdadera diferencia entre los dos es cómo se asigna el manejo de eventos. Nunca verá un delegado registrarse para un evento. Nunca sabrá si está manejando el evento hasta que ocurra y el delegador llame a un método público.

Ventaja de delegación

Este patrón es muy rígido y con los diseños más habituales es más simple y generalmente más robusto. Te obliga a declarar tu controlador de eventos por adelantado al momento de inicializar la fuente del evento potencial. Si necesita que alguien dirija el tráfico, asigne un director de tráfico antes de abrir la calle. En el caso del observador, dejaría que el policía de tráfico elija cuándo dirigir el tráfico cada vez que lo desee.

Desventaja de delegación

La desventaja de este diseño es que no es flexible. Si implementara algún código para suscribirse a un periódico, el periódico / delegado tendría que identificar exactamente quién puede leer las noticias en el momento en que se crean. Con el patrón de observador, pueden registrarse más adelante en cualquier momento y el periódico solo tendrá que saber que una nueva persona se ha registrado.

¿Cuándo elegir la delegación?

Cuando necesite un observador (es) específico (s) con seguridad y no haya razón para cambiar quién está observando, entonces el diseño rígido del patrón de delegación será beneficioso.

Por ejemplo, necesita una clase / objeto para manejar la creación de una ventana emergente para un error específico. No hay muchas razones por las cuales en tiempo de ejecución necesitaría cambiar quién está manejando un error específico, por lo que delegar el error "Memoria insuficiente" a una sola entidad tendría sentido. Crear una matriz de posibles controladores y luego hacer que esos controladores se registren para el error "Memoria insuficiente" no tendría mucho sentido; eso sería un ejemplo del uso del patrón de observador en esta situación. En el tiempo de ejecución, es posible que desee cambiar qué métodos se llaman o qué "delegado" se llama para eventos variables, pero cambiar un controlador de eventos por un evento específico en tiempo de ejecución no es normal.

No es imposible intercambiar delegados como lo haría en el patrón de observación, es simplemente complicado. En el mundo real, tal vez desee intercambiar policías de tráfico para que un nuevo delegador esté manejando el tráfico. Se podría argumentar que un mejor diseño haría que el delegado original fuera una estación de policía y no un solo oficial de policía, sino que estoy divagando ...

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.