何となくRxJavaを使ってるけど正直よく分かってない人が読むと良さそうな記事・基礎編

  • 76
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

RxJava Advent Calendar 2015 6日目の記事です。

私のように、「見よう見真似でRxJavaを使い始めてAsyncTaskとか潰せるし最高なんだけどぶっちゃけRxとかFRPとかよく分からないしObservableとかsubscribeとか言葉の意味もしっくり来ないし発展的な話も色々あるしどうすればいいの」って人が読んだ方が良さそうな記事を選んでみました。

色々言及しようとしたら長くなってしまったので、本記事は前編・基礎編です。

前提:RxJava, RxAndroid, ReactiveX, Rx, Reactive Extentions, FRPの違い

こやつらの違いを知っておくと後が楽なので、ざっくりと見ておきます。

RxJava

ReactiveX(後述)をJava (JVM)で使えるようにした物です。Netflix社製。
https://github.com/ReactiveX/RxJava

RxAndroid

RxJavaをAndroidでも使えるようにした物です。
よって「AndroidでRxJavaを書いてる」って人はRxAndroidも使っています。
https://github.com/ReactiveX/RxAndroid

「AndroidでRxAndroidは必須ではない」というコメントをいただいて、RxAndroidのREADMEを読み返してみました。

This module adds the minimum classes to RxJava that make writing reactive components in Android applications easy and hassle-free. More specifically, it provides a Scheduler that schedules on the main UI thread or any given Handler.

このモジュールはAndroidアプリでリアクティブなコンポーネントを書くために必要な最低限のクラスをRxJavaに提供します。もっと具体的に言うと、メインUIスレッドやHandlerの上でスケジューリングを行うSchedulerを提供します。

なるほど、RxAndroidとは即ちSchedulerをRxJavaに追加する物なのですね。
リポジトリを見てみると、クラスが5つしか無いように見えます。
https://github.com/ReactiveX/RxAndroid/tree/master/rxandroid/src/main/java/rx/android

確かに、これなら「AndroidでRxJavaを使おうとするとRxAndroidを必ず使う」と言うのは誤りですね。

ReactiveX

逆説的な言い方ですが、"RxJavaのようなデザインパターン"の事です。
このReactiveXの具体的な実装として、RxJavaなど色々なRx*があります。
http://reactivex.io/

Reactive Extentions (Rx)

基本的にはReactiveXと殆ど同じような文脈で使われます。
ただし、正確には「ReactiveXの前進?となったMicrosoft社のオープンソースプロジェクト、またはMicrosoft社製のReactiveX実装」を指すようです。

Microsoftのプロジェクトページを見ると同じロゴが使われていますし、ReactiveXから辿れるRx.NetRxCppなどのREADMEにはMicrosoft OSS projectに関する言及があります。

一方、我々が使うRxJavaはNetflix社製です。
ここで、Rx.NetやRxCppはOrganizationがReactive-Extentions, RxJavaはReactiveXになっています。
前者は明示的にThe Cloud Programmability Group at Microsoftと名乗っていますが、後者はReactiveXとしか名乗っていません。
前者のメンバーは全員Microsoft社関者のようですが、後者はNetflix社、Facebook社、Square社(Jake神)など色々です。

確かに、殆ど同じものであるものの、Reactive Extentions(Rx)をReactiveXを「Microsoftかそうでないか」という区別はできるようです。
ここもコメントをいただきましたが、このような区別は正しくなく、「Reactive ExtentionsはReactiveXの一つである」という見方が正しいようです。
詳しくはコメント欄の参照をお願いいたします。

ちなみにこのMicrosoft社のプロジェクトは以下の様な歴史があるようです。

Rxは、2009年11月18日に、マイクロソフトの開発部門およびMicrosoft Researchの実験的なプロジェクトを公開するポータル・サイト「Microsoft DevLabs」にてページが開設され、その後、1年半に渡り細かく試験的なリリースが続けられてきた。DevLabsの実験的なプロジェクトは、正式な製品に昇格するものもあれば、最終的には打ち切られてしまうものもある。Rxは、2011年1月21日に、正式な製品として認められ、以降、プロジェクトのページはData Developer Centerへと移行した。

http://www.atmarkit.co.jp/fdotnet/introrx/introrx_01/introrx_01_01.html

現在の各プロジェクトはこの流れを組んでいるのですね。

FRP; Functional Reactive Programming

私自身よく分かっていないので割愛します。
とりあえず「Rxと似ているけどちょっと違うもの」と覚えておけば最初は大丈夫そうです。
ReactiveXの公式ページでも、↓のように言われています。

It is sometimes called “functional reactive programming” but this is a misnomer. ReactiveX may be functional, and it may be reactive, but “functional reactive programming” is a different animal.

時々ReacitveXはFRPだって言われるけれどもそいつは間違いだ。ReactiveXは関数型かもしれないし、リアクティブかもしれないけれど、それでもFRPとは別物だ。

前提はこの辺にして、読むべき記事について述べていきます。

ReactiveXの基礎固め

【翻訳】あなたが求めていたリアクティブプログラミング入門

いきなり重い記事ですが、ReactiveXの基礎を学びつつ、ReactiveXの世界は広いことを体感できます。頑張って読みましょう。
サンプルコードはRxJS (JavaScript)ですが、RxJavaと同じReactiveXなので、RxJavaを触ったことがある人であれば大体読めます。

また、概念が頭の中で整理されると、曖昧な用語に対する理解も多少進むでしょう。
私が特に気に入った一文はこれです。

公式な用語ではこのようなストリームは "Observable" と言い、事実これは観測可能なものだ。しかし私はこれを馬鹿げた名前だと感じるので、ストリームと呼ぶ。

observeとsubscribeの違い

RxJavaを触っていて、「observeとsubscribeの概念の違いがよく分からないなあ」と思ったことはないでしょうか?
【翻訳】あなたが求めていたリアクティブプログラミング入門でも、こんなこんな一文があります。

Rx.Observable.create()は、observer (他の言葉で言えば "subscriber") にデータイベント (onNext()) やエラー (onError()) の情報を伝えることによって、カスタムストリームを作り出す。

RxJavaにおいて、observe(r)とsubscribe(r)という言葉は同じ意味で使われるのでしょうか?
その意味では、例えばobserveOn()subscribeOn()は同じ物であるはずですが、どうやら似て非なるものらしいです。

詳解RxJava:Scheduler、非同期処理、subscribe/unsubscribe - subscribeOn()とobserveOn()の違いって?

また、RxJavaのクラスであるObserverSubscriberの違いを調べてみると、明確に違いがあることが分かります。

public abstract class Subscriber<T> implements Observer<T>, Subscription

So a Subscriber is the implementation of the Observer,

What is the difference between an Observer and a Subscriber?

Rxの源流にObserverパターンがあることを考えると、Observerがinterfaceで、subscriberがその実装なのは、関係性としては分からないでもないです。

一方、ObservableはあるのにSubscribableはありません。
Observable#subscribe()はあるのにObservable#observe()はありません。
SubscriptionはあるのにObservationはありません。

この辺がどうしても一貫性が無いように感じてしまうのですが、これはRxJavaの歴史を紐解いて行けば自ずと理解できるんでしょうか?
結局両者の明確な違いは分からず終いですが、文脈により「同じもの」と捉えられる場合と「異なるもの」と捉えられる場合があるようです。

RxJavaはPromiseみたいなもの

【翻訳】あなたが求めていたリアクティブプログラミング入門では"Promise"への言及があります。よく「RxJavaはPromiseみたいなもの」という説明を見ますが、いやPromiseも知らないから!と思った人も多いでしょう。せっかくなのでここで軽く見ておきましょう。

今更だけどPromise入門

サンプルコードを見て「PromiseってRxJavaみたいだなあ」と思ったことでしょう。私もそう思いました。先にRxJavaを知ったので印象が逆ですが、これで「PromiseとRxJava (ReactiveX)は似てる」ということがお分かりいただけたでしょう。後発のRxJavaに対して人々が「これはPromiseみたいなもの」と説明するのも納得です。

PromiseとReactiveXの違いも見ておきましょう。これは正に今回のAdvent Calendarでぴったりな記事がありました。

RxとPromise: 「RxJavaでPromiseしたい!!!11」

最後に

以上、ReactiveX周りの用語から基礎までを、色々な記事を紹介しつつざっくりと見てきました。
RxJavaの記事と言いつつ殆どReactiveXの話になってしまいましたが・・・次の記事では「応用編 やや発展編」と銘打って、(今度こそ)RxJavaをよく分かってない私のような人向けの記事を見ていく予定です。

追記:書きました。
何となくRxJavaを使ってるけど正直よく分かってない人が読むと良さそうな記事・やや発展編

この投稿は RxJava Advent Calendar 20156日目の記事です。