ReactiveCocoa vs RxSwift: ¿pros y contras?

Resuelto Orion Edwards asked hace 9 años • 1 respuestas

Ahora con Swift, la gente de ReactiveCocoa lo ha reescrito en la versión 3.0 para Swift.

Además, ha surgido otro proyecto llamado RxSwift .

Me pregunto si la gente podría agregar información sobre cuáles son las diferencias en el diseño/api/filosofía de los dos marcos (por favor, en el espíritu de SO, limítese a las cosas que son ciertas, en lugar de opiniones sobre cuál es "mejor")

Para empezar, mi impresión inicial al leer su Léame es:

  • Como alguien que está familiarizado con el C# Rx "real" de Microsoft, RxSwift parece mucho más reconocible.
  • ReactiveCococa parece haber entrado ahora en su propio espacio, introduciendo nuevas abstracciones como Signals vs SignalProducers y Lifting. Por un lado, esto parece aclarar algunas situaciones (qué es una señal Caliente o Fría) pero, por otro lado, parece aumentar MUCHO la complejidad del marco.
Orion Edwards avatar Sep 13 '15 02:09 Orion Edwards
Aceptado

Esta es una muy buena pregunta. Comparar los dos mundos es muy difícil. Rx es una adaptación de lo que son las Reactive Extensions en otros lenguajes como C#, Java o JS.

Reactive Cocoa se inspiró en la programación reactiva funcional , pero en los últimos meses también se ha señalado que está inspirado en las extensiones reactivas . El resultado es un marco que comparte algunas cosas con Rx, pero tiene nombres con origen en FRP.

Lo primero que hay que decir es que ni RAC ni RxSwift son implementaciones de Programación Reactiva Funcional , según la definición del concepto de Conal . A partir de este punto, todo se puede reducir a cómo cada marco maneja los efectos secundarios y algunos otros componentes.

Hablemos de la comunidad y de la metatecnología :

  • RAC es un proyecto de 3 años, nacido en Objective-C y luego portado a Swift (con puentes) para la versión 3.0, después de abandonar por completo el trabajo en curso en Objective-C.
  • RxSwift es un proyecto que tiene unos meses y parece tener impulso en la comunidad en este momento. Una cosa que es importante para RxSwift es que está bajo la organización ReactiveX y que todas las demás implementaciones funcionan de la misma manera. Aprender a manejar RxSwift hará que trabajar con Rx.Net, RxJava o RxJS sea una tarea sencilla y solo una cuestión. de la sintaxis del lenguaje. Podría decir que se basa en la filosofía de aprender una vez, aplicar en todas partes .

Ahora es el momento de las cosas tecnológicas.

Entidades productoras/observadoras

RAC 3.0 tiene 2 entidades principales: Signalla SignalProducerprimera publica eventos independientemente de que un suscriptor esté conectado o no, la segunda requiere que startse produzcan señales/eventos. Este diseño ha sido creado para separar el tedioso concepto de observables fríos y calientes, que ha sido fuente de confusión para muchos desarrolladores. Es por eso que las diferencias pueden reducirse a cómo manejan los efectos secundarios .

En RxSwift, Signaly SignalProducerse traduce como Observable, puede parecer confuso, pero estas 2 entidades son en realidad lo mismo en el mundo Rx. ObservableSe debe crear un diseño con s en RxSwift considerando si son fríos o calientes, podría parecer una complejidad innecesaria, pero una vez que entendiste cómo funcionan (y nuevamente, caliente/frío/tibio se trata solo de los efectos secundarios al suscribirse/observar ) pueden ser domesticados.

En ambos mundos, el concepto de suscripción es básicamente el mismo, hay una pequeña diferencia que introdujo RAC y es el interruptionevento en el que Signalse elimina antes de que se haya enviado el evento de finalización. En resumen, ambos tienen el siguiente tipo de eventos:

  • Next, para calcular el nuevo valor recibido
  • Error, para calcular un error y completar la transmisión, cancelando la suscripción de todos los observadores.
  • Complete, para marcar la transmisión como completada y cancelar la suscripción de todos los observadores.

RAC además tiene interruptedque se envía cuando Signalse elimina antes de completarse ya sea correctamente o con un error.

Escribir manualmente

En RAC, Signal/ SignalProducerson entidades de solo lectura, no se pueden administrar desde afuera, lo mismo ocurre Observableen RxSwift. Para convertir un Signal/ SignalProduceren una entidad que se puede escribir, debe usar la pipe()función para devolver un elemento controlado manualmente. En el espacio Rx, este es un tipo diferente llamado Subject.

Si el concepto de lectura/escritura le resulta desconocido, se puede hacer una buena analogía con Future/ . PromiseA Futurees un marcador de posición de solo lectura, como Signal/ SignalProducery Observable, por otro lado, a Promisese puede completar manualmente, como para pipe()y Subject.

Programadores

Esta entidad es bastante similar en ambos mundos, los mismos conceptos, pero RAC es solo en serie, en cambio, RxSwift también presenta programadores concurrentes.

Composición

La composición es la característica clave de la programación reactiva. Componer flujos es la esencia de ambos marcos; en RxSwift también se les llama secuencias .

Todas las entidades observables en RxSwift son de tipo ObservableType, por lo que componemos instancias de Subjecty Observablecon los mismos operadores, sin ninguna preocupación adicional.

En el espacio RAC, Signaly SignalProducerson 2 entidades diferentes y tenemos que liftseguir SignalProducerpara poder componer lo que se produce con instancias de Signal. Las dos entidades tienen sus propios operadores, por lo que cuando necesitas mezclar cosas, debes asegurarte de que un determinado operador esté disponible; por otro lado, te olvidas de los observables fríos/calientes.

Acerca de esta parte, Colin Eberhardt la resumió muy bien:

Al observar la API actual, las operaciones de señal se centran principalmente en el "siguiente" evento, lo que le permite transformar valores, omitir, retrasar, combinar y observar en diferentes subprocesos. Mientras que la API del productor de señales se ocupa principalmente de los eventos del ciclo de vida de la señal (completado, error), con operaciones que incluyen then, flatMap, takeUntil y catch.

Extra

RAC también tiene el concepto de Actiony Property, el primero es un tipo para calcular efectos secundarios, principalmente relacionados con la interacción del usuario, el segundo es interesante cuando se observa un valor para realizar una tarea cuando el valor ha cambiado. En RxSwift, esto se Actiontraduce nuevamente en Observable, esto se muestra muy bien en RxCocoa, una integración de primitivas de Rx tanto para iOS como para Mac. Los RAC Propertyse pueden traducir a Variable(o BehaviourSubject) en RxSwift.

Es importante entender que Property/ Variablees la forma que tenemos de unir el mundo imperativo con la naturaleza declarativa de la Programación Reactiva, por lo que a veces es un componente fundamental cuando se trata de bibliotecas de terceros o funcionalidades centrales del espacio iOS/Mac.

Conclusión

RAC y RxSwift son dos bestias completamente diferentes, el primero tiene una larga historia en el espacio Cocoa y muchos contribuyentes, el segundo es bastante joven, pero se basa en conceptos que han demostrado ser efectivos en otros lenguajes como Java, JS o .NETO. La decisión sobre cuál es mejor depende de la preferencia. RAC afirma que la separación de los observables frío/calor era necesaria y esa es la característica principal del marco, RxSwift dice que la unificación de ellos es mejor que la separación, nuevamente se trata solo de cómo se manejan/realizan los efectos secundarios.

RAC 3.0 parece haber introducido cierta complejidad inesperada además del objetivo principal de separar observables fríos y calientes, como el concepto de interrupción, dividir operadores entre 2 entidades e introducir algún comportamiento imperativo como startcomenzar a producir señales. Para algunas personas, estas cosas pueden ser algo agradable o incluso una característica excelente, para otras pueden ser simplemente innecesarias o incluso peligrosas. Otra cosa para recordar es que RAC está tratando de mantenerse al día con las convenciones de Cocoa tanto como sea posible, por lo que si es un desarrollador experimentado de Cocoa, debería sentirse más cómodo trabajando con él en lugar de con RxSwift.

RxSwift, por otro lado, vive con todas las desventajas, como los observables fríos y calientes, pero también las cosas buenas de Reactive Extensions. Pasar de RxJS, RxJava o Rx.Net a RxSwift es algo simple, todos los conceptos son iguales, por lo que esto hace que encontrar material sea bastante interesante, tal vez el mismo problema al que te enfrentas ahora haya sido resuelto por alguien en RxJava y la solución. Se puede volver a aplicar teniendo en cuenta la plataforma.

Cuál hay que elegir es definitivamente una cuestión de preferencia, desde una perspectiva objetiva es imposible decir cuál es mejor. La única forma es iniciar Xcode, probar ambos y elegir el que le resulte más cómodo para trabajar. Son 2 implementaciones de conceptos similares, intentando conseguir el mismo objetivo: simplificar el desarrollo de software.

bontoJR avatar Sep 15 '2015 08:09 bontoJR