対象読者
- Java経験者(初心者可)
- RxJava未経験者
- リアクティブプログラミング未経験者
RxJavaとは
RxJavaは、Javaでリアクティブプログラミングを行うためのライブラリです。このライブラリは軽量であり、また、他のライブラリに対する依存がないのでRxJavaのjarをパスに通すだけで使えるようになります。対応しているJavaのバージョンは6からで、さらにAndroidもバージョン2.3(Gingerbread)からサポートしています。
そして、RxJavaは厳密には関数型リアクティブプログラミング(Functional Reactive Programming)ではないのですが、引数に関数型インターフェースを受け取るメソッドを使っているので、関数型プログラミングのように関数を組み合わせていくことで、データの変換やフィルタなどを柔軟に組み立てれるようになっています。
リアクティブプログラミングとは
リアクティブプログラミングとは、データが流れるように来ること(ストリーム)に着目し、データを受け取るたびに関連したプログラムが反応(リアクション)して処理を行うようにするプログラミングの考え方です。
このデータのストリームとは、例えばGPSを利用して位置情報が変わるたびに送信されるデータの流れをイメージしてもらうと分かりやすいかもしれません。移動し位置情報が変わるたびにデータが送信され、立ち止まればデータの送信が止まるように、生成されるデータをすべてまとめて送信するのではなく、個々のデータが生成される度に順に送信していきます。このようなデータの流れのことをデータストリームと言います。
このデータストリームはイベントとも関連していて、文字列を入力するという行為は、入力したデータが順に生成されているとみることができます。例えば「abc」という入力は、入力のイベントが発生するたびに
- 「a」
- 「ab」
- 「abc」
と、データが発生していると見なすことができます。同様にボタンを押す行為に関しても、具体的なデータがなくても「ボタンを押した」というデータが生成されていると見なすことが可能です。ボタンを複数回押した場合、その押した数だけ「ボタンを押した」というデータが生成されていることになります。つまりイベントも、発生するたびにデータを発信するデータストリームとして扱うことが可能になります。
リアクティブプログラミングでは、このようなデータストリームから流れてくるデータに対し、そのデータを受け取ったプログラムが、そのたびに処理をしていく作りになっています。つまり、プログラムが必要なデータを自分から取得し処理をするのではなく、送られてきたデータを受け取るたびに反応して処理をする(リアクティブな処理をする)ようなプログラムにすることがリアクティブプログラミングになります。
例えば、商品価格と税率から税額を計算するプログラムがあったとします。リアクティブプログラミングでない場合、商品価格と税率の値を取得しただけでは何も起こりません。値を取得した後に「税額の計算処理を行う」というアクションが実行されて初めて税額が算出されます。そして、税額を計算した後に商品価格の値が変わったとしても、再び計算処理のアクションが実行されない限り税額の値は変わりません。
しかし、これがリアクティブプログラミングの場合、商品価格の値が変化するたびに税額が計算され表示されるようになります。これは商品価格の値が変化するたびに税額を計算するプログラムに値が送信され、プログラムが値を受け取ると税額の計算処理を行い、その計算結果が税額に反映されるためです。そのため、商品価格の値が変わるたびに商品価格が通知され、税額が自動的に算出されるようになります。
これだけだと、商品価格にListenerをつけて自動で計算できるようにしたプログラムとどう違うのか疑問に思われるかもしれません。この場合、リアクティブプログラミングなのかどうかは、何が処理を行うのかの意識の違いになるかと考えられます。例えば、商品価格が変更されListenerが反応して、商品価格が税額を計算して値を反映しているという意識の場合は、リアクティブプログラミングの考え方にはなりません。
これをListenerが反応したことによって、税額に新たな商品価格が渡され、税額にて計算のプログラムが実行されて、その結果を税額自身に反映していると意識している場合は、リアクティブプログラミングの考え方になります。
そのため、今回のような簡単なプログラムの場合は、前者も後者もソースコード上ではまったく同じになる可能性はあります。しかし、このプログラミング上の考え方の違いによって、どのプログラムが何をするのかの範囲が変わってきます。行うべき処理が複雑になってきたり、商品価格の変更によって値が変わる項目が増えてきたりするにつれ、どこで処理を行うのかの比重が変わり、ソースコード上にも違いが現れてくるでしょう。
リアクティブプログラミングでは、データの生産側(今回の例では商品価格)はデータを渡すところまでが自身の責任になります。そのため、データの生産側はデータの消費側(今回の例では税額)の処理についてはそのデータを使って何をしているのかを意識しなくてもよくなります。そしてそのことは、データの生産側は消費側で何をしているのかは関係がなくなり、消費側の処理を待つ必要もなくなるので、データの通知をした後に、消費側の処理が途中であっても、すぐに生産側の次の処理を行えます。こうすることで非同期処理を容易に実現できるようになります。
また、システムの構築という点で見ても、リアクティブプログラミングの考え方はマイクロサービスなどの分散システムで稼働するプログラムにも向いており、現在大きな注目を浴びているプログラミング手法の一つになっています。
ただし、紛らわしいことに、「リアクティブシステム」と言った場合、「リアクティブプログラミングで実装されたシステム」のことを表さないことに注意しないといけません。リアクティブシステムとは、簡単に説明すると、メッセージを送ることで処理を行い、状況に応じてスケールアウトやスケールインが自動で行われ、障害の耐性を高めることによって、常に迅速な応答を得ることができるシステムのことを言います。そのため、このリアクティブシステムはプログラムだけではなくインフラの条件も必要となります。そして各サービスに対しては別にリアクティブプログラミングで実装していなくても、リアクティブシステムの構築は可能でもあります。