2011-04-07 16 views
6

¿Existen directrices sobre cuándo debe usar un delegado para la asociación indirecta y un observador?Patrones de delegados vs. observadores

En C#, puede usar delegados para llamadas simples. Supongo que los punteros para funcionar y los punteros a las funciones de los miembros también se pueden considerar como delegados (¿estoy en lo cierto?).

Me doy cuenta de que si uso un observador, necesita crear una interfaz e implementarlo, por lo que es más fuertemente tipado y la relación es más formal. Para un delegado, siempre que la firma de la función y la accesibilidad coincidan, puede "conectarlos".

¿Los delegados hacen que el patrón de observador sea irrelevante? ¿Cómo se decide sobre un delegado frente a un patrón de observador?

+2

Btw: en .NET 4, tales interfaces ya están allí: 'IObservable ' y 'IObserver '. Y puede usar las Extensiones reactivas para componer fácilmente observables y observadores. –

+0

Ver http: // stackoverflow.com/questions/550785/c-events-or-an-observer-interface-pros-cons – jpierson

Respuesta

8

El patrón de observador ya está implementado para usted en forma de events.

La ventaja de los eventos es que pueden tener varios suscriptores, mientras que con un delegado, solo puede tener uno. Esto hace que los eventos sean mucho mejores para las interfaces públicas y los escenarios en los que no se tiene control total sobre quién quiere que se le notifique que sucede algo. En realidad, los eventos son solo listas de delegados administradas automáticamente. Tendrás que ver qué tiene más sentido en tu escenario.

Editar:As commenter Rabbi mentions, lo anterior no es del todo cierto, ya que cualquier delegado puede convertirse en un delegado de multidifusión. El propósito del modificador de eventos es crear un delegado que solo pueda invocarse dentro de la clase que lo define. Esto es más útil para asegurar la encapsulación en las interfaces públicas.

+0

Un evento es solo un tipo especial de delegado. ¿No es para que un delegado pueda tener múltiples suscriptores? Creo que un evento es un delegado que solo tiene operadores '+ =' y '- =', y un delegado también puede asignarse ('=') para que pueda sobrescribir todos los suscriptores cuando use un delegado en lugar de un evento. ¿Estoy en lo correcto? – Rodi

+0

El concepto de evento de C# es para un delegado, más o menos, lo que una propiedad es para un campo. Puede cambiar lo que hacen las operaciones add/remove, vea el ejemplo 2 [aquí] (http://msdn.microsoft.com/en-us/library/8627sbea (v = vs.71) .aspx). Cuando no lo hace, genera un [MulticastDelegate] (http://msdn.microsoft.com/en-us/library/system.multicastdelegate.aspx) para usted bajo el capó. –

+0

sí. Sin embargo, lo que estaba tratando de decir es que los eventos solo usan operadores '+ =' y '- =' aun cuando se puede cambiar el comportamiento de esos operadores usando construcciones 'add' y' remove' similares a propiedades. La asignación ('=' operador) no se puede hacer en eventos. Podría estar equivocado ya que soy demasiado flojo para probarlo. – Rodi

1

Los delegados se pueden usar para implementar el patrón de observación: piense en los eventos.

hacerlo sin eventos miren aquí: http://www.dofactory.com/Patterns/PatternObserver.aspx

No tardaría mucho que refactorizar que en el uso de los delegados si preferido.

La única ventaja que se me ocurre al implementar una interfaz es la coherencia del nombre del miembro en todas las implementaciones.

3

Una de las ventajas del patrón de observador es que si tiene una gran cantidad de eventos generalmente suscritos por una parte interesada, pasar un solo objeto a un método para suscribirse a los eventos es mucho más fácil que suscribirse a cada evento individualmente Con la falta de C de la especificación de interfaces y métodos para las clases anónimas as can be done with Java, la implementación del patrón de observación se vuelve un poco más laboriosa, por lo que la mayoría opta por utilizar eventos de todos modos.

Otra ventaja del patrón de observador tradicional es que se maneja mejor en los casos en que necesita interrogar al suscriptor por algún motivo. He encontrado esta necesidad con objetos que pasan un límite del servicio web donde hay problemas con los delegados, mientras que el patrón del observador es simplemente una referencia a otro objeto, por lo que funciona bien siempre que la serialización mantenga la integridad de las referencias dentro del objeto gráfico como el NetDataContractSerializer lo hace. En estos casos, es posible discriminar entre suscriptores que deben eliminarse antes de establecer el límite del servicio en función de si el suscriptor al que se hace referencia también está dentro del mismo gráfico de objetos.

Cuestiones relacionadas