2010-05-16 16 views
11

¿Hay algún equivalente de Reactive Extensions (.NET) para Java?Extensiones reactivas para Java

Sobre Rx (Reactive Extensions)

Rx es una biblioteca para componer programas asincrónicos y basados ​​en eventos utilizando colecciones observables.

Conozco los motores de reglas como Drools de JBOSS, pero ¿hay alguna otra manera que se acerque más al enfoque de Microsoft .NET?

Respuesta

11

No conozco ninguno, y francamente sería difícil hacerlo de una manera tan ordenada. El lado de enhebrar está bien; Java es perfectamente capaz cuando se trata de enhebrar ... pero por el momento, el lenguaje simplemente no admite las características adecuadas.

Una de las características de diseño de LINQ es que todo se basa en interfaces y luego los métodos de extensión se utilizan para agregar funcionalidad adicional. Eso permite que el código se lea con fluidez - imagínese si tuviera que escribir:

IObservable<int> = Observable.Select(
         Observable.Where(
          source, x => x.SomeCondition) 
         x => x.SomeProjection); 

Ick. El método de extensión es mucho más elegante:

IObservable<int> = source.Where(x => x.SomeCondition) 
         .Select(x => x.SomeProjection); 

ahora una versión de Java podría basarse en una clase base abstracta en su lugar, pero eso sería perder parte de la elegancia.

Próximas expresiones de lambda y conversiones de grupos de métodos: estas son realmente fundamentales para LINQ en general; el equivalente más cercano en Java (clases internas anónimas) son demasiado feos para usarse en cualquier lugar donde use una expresión lambda en C#.

Básicamente, una versión Java de Rx sería factible, pero no sería tan elegante como la versión C# - que es probablemente la razón por la que no se ha hecho hasta donde yo sé. Puede haber otras bibliotecas "controladas por asincronía" para Java, pero es poco probable que sean tan completas y ordenadas como Rx.

Es posible que los cambios en Java 7 harán esto más factible; por lo que yo sé, no se están introduciendo métodos de extensión, pero una clase base abstracta versión gustaría ser razonable si la sintaxis lambda termina siendo bien ...

+0

Ok, gracias. Tal vez esto sea más factible en Java 7 con cierres. –

+2

Ahora puede escribir esto en Java: IObservable = source.where (condition()). Select (selector()). ToArray(); Consulte github.com/nicholas22/jpropel-light –

1

Usted podría considerar portar raix (wiki), escrito en ActionScript 3, a Java 7 cuando llega. El proyecto (el mío) es de código abierto e incluye pruebas de unidad de caja negra de la versión .NET del marco para garantizar la compatibilidad.

Como Java, AS3 no admite ni métodos de extensión ni expresiones lambda, por lo que la implementación puede ser similar. Una vez dicho esto, deberá tener cuidado con las condiciones de carrera, ya que el AVM no admite subprocesos, por lo que no hay ningún código de bloqueo en RxA.

+0

@ richard-szalay, gracias por el puntero. –

3

Si todavía está interesado, he estado trabajando en un Java library últimamente, que ofrece la mayoría de los operadores de Rx en el lado reactivo e interactivo también.

Definitivamente no es tan agradable como el .NET. Java no tiene métodos de extensión o tipos de funciones, por lo tanto, todo se debe invocar mediante un método estático y clases internas. En.NET:

Observable.Range(0, 10).SelectMany(
    o => Observable.Range(0, o) 
).Run(Console.WriteLine); 

Mi biblioteca:

Reactive.run(
    Reactive.selectMany(
     Reactive.range(0, 10), 
     new Func1<Observable<Integer>, Integer>() { 
      public Observable<Integer> invoke(Integer param1) { 
       return Reactive.range(0, param1); 
     } 
    }  
), Reactive.println()); 

Interactive.run(
    Interactive.selectMany(
     Interactive.range(0, 10), 
     new Func1<Iterable<Integer>, Integer>() { 
      public Iterable<Integer> invoke(Integer param1) { 
       return Interactive.range(0, param1); 
     } 
    }  
), Interactive.println()); 

utilizo Func0, Func1, tipos FUNC2 de lambda y el tipo que se puede cerrar para anular el registro. Una vez que Java obtiene ciudadanos de primera clase, estos tipos de FuncX pueden ser simplemente reemplazados. Closeable puede ser utilizado por una mejora de try-with-resources de Java 7. La tercera fealdad se debe a la inferencia de tipo débil en varios lugares.

+1

¡Las importaciones estáticas pueden mejorar enormemente la legibilidad! – thSoft

18

Según este NetFlix blog post, han portado Rx a Java. No parece estar disponible aún, pero sí tienen un historial de lanzamiento de herramientas desarrolladas internamente como de código abierto, por lo que espero que se lance finalmente.

+11

RxJava de Netflix ahora está disponible en https://github.com/Netflix/RxJava –

1

RxJava (RX portado por Netflix) está disponible y estable aquí: https://github.com/ReactiveX/RxJava.

¡Incluso funciona con la sintaxis lambda de Java 8 bastante bien! Usted puede hacer cosas por el estilo:

Observable 
    .from(Arrays.asList(1, 2, 3, 4, 5)) 
    .filter(val -> val % 2 == 0) 
    .map(val -> val * val) 
    .scan(0, (prev, curr) -> prev + curr) 
    .subscribe(System.out::println) 

bastante fresco de una?

Cuestiones relacionadas