2012-02-15 16 views
18

He tenido un mini-discussion on the topic en otro hilo, y me gustaría tener la opinión de la gente sobre los lados "malos" de los sujetos.RX Temas: ¿se deben evitar?

Las personas que frecuentan el foro de RX saben que E.Meijer does not like Subjects. Si bien tengo un profundo respeto por la opinión del creador de RX, durante un par de años he estado utilizando temas bastante extensos en varios proyectos y no he tenido ningún problema arquitectónico o error debido a ellos.

El único "inconveniente" con los sujetos que puedo nombrar es que no son "reutilizables": después de haber completado un observable en un tema, necesita volver a crear una instancia antes de que los nuevos suscriptores puedan recibir eventos.

"Code smell" y "Do not like them" necesitan ser respaldados por ejemplos "pragmáticos": ¿puede poner en conocimiento de usted situaciones posibles cuando utiliza un Subject que puede provocar una falla o un problema? O tal vez piense que son fáciles e inofensivos por completo, luego intente definir un área donde se usarán.

Respuesta

22

Erik Meijer está pensando de una manera puramente funcional: los sujetos son las variables mutables de Rx. Por lo tanto, en el uso general, tiene razón: usar temas a veces es una manera de desconectarse de Thinking Functionally, y si los usa demasiado, está intentando remar río arriba.

¡Sin embargo! El tema es extremadamente útil cuando interactúa con el mundo no funcional de .NET. ¿Envolver un evento o método de devolución de llamada? Los sujetos son geniales para eso. ¿Tratas de poner una "interfaz" Rx en algún código existente? Usa un sujeto!

+3

Suena razonable. Excepto que sugeriría que ya hay formas de envolver Eventos, es decir, Observable.FromEvent (Patrón), que de nuevo es más preferible a los temas. –

+2

Creo que no solo se trata simplemente de envolver los eventos y sincronizar llamadas, sino también de usar datos de ellos. Por ejemplo, al envolver el par de llamadas asíncronas 'BeginRead' /' EndRead' - 'EndRead' solo devuelve el número de bytes leídos, para obtener los datos reales debe acceder al conjunto de bytes variable pasado a' BeginRead'. – Tyson

+0

Buena explicación. – axel22

2

Yo uso Subject/Publish cuando los combinadores reactivos se están duplicando debido a lazy eval.

Sin embargo, para uso casual, creo que los temas son un poco pesados: OnNext podría ser un cuello de botella potencial, aparece como un punto caliente durante la creación de perfiles, tal vez debido a las comprobaciones de concurrencia al tiempo que aumenta el valor para los suscriptores.

Creo que también es más limpio para los observables que usted sabe que son calientes por definición.

6

Parece que muchos comentaristas están hablando el uno del otro.

La última vez que usé un Asunto fue cuando tuve que pasar un delegado a un middleware en una llamada de inicialización para que me devolviera la llamada cuando sucedió algo. El delegado tenía la firma familiar de argumentos de evento, pero no pude usar FromEvent porque no hubo ningún evento.

No me sentí mal por eso, no vi ninguna otra opción.

Básicamente usé Temas solo cuando estoy originando algún evento y poniéndolo en el mundo Rx, o cuando necesito un control para un futuro suscriptor que aún no ha llegado. Los sujetos me permiten vincular lo que tengo ahora con un suscriptor posterior.

+0

Deduzco de su comentario que el método 'Observable.FromEvent' no atendía a los delegados regulares en ese momento. O puede ser que todavía no lo hagan y lo obligan a decir que se trata de un "evento" en lugar de simplemente un delegado. Tengo que verificar eso. ¿Pero podría publicar algún código para mostrar lo que hizo? Tengo curiosidad por entender la forma en que usaste 'Asunto '. –

1

Una razón por la que sería cauteloso al usar un Subject<T> como parte de la API pública es que mezcla preocupaciones; un observador es una preocupación distinta de la observable.

¿Qué pasa si algún observador malhechor llama OnNext o OnCompletedOnError o en el Subject<T> en el que sólo se supone que es un observador ?

Incluso si no es parte de la API, y la guardas en tu servidor como un campo de respaldo privado, el solo hecho de que tenga un doble rol es inquietante. En el caso de usarlo como campo de respaldo, solo espera que desempeñe un rol/preocupación, el de un observable. Sin embargo, tiene el potencial de hacer dos cosas y eso es solo mentalmente perturbador.