22時に寝ようと思って2時に寝る。

備忘録や日記を書いてます。きょうは早く寝よう。

RxJava - リアクティブプログラミングとは

最近、学び始めたリアクティブプログラミングについて備忘録としてまとめていきます。今回は、概要について触れます。

リアクティブプログラミングとは

リアクティブプログラミング(Reactive Programming)は、最近注目されているプログラミングパラダイムの一つで、特定の言語やフレームワークにかかわらず適用できるスタイルのようなものです。

  • データフローの定義
  • 変更の伝搬

以上の2つの段階を記述することで、あとは変更があるたびに伝搬させることができ、何らかのイベントに反応するプログラムを比較的容易に実現することが可能になります。

例えば、GPSの位置情報を取得するときに適用できます。移動し座標(緯度・軽度)が変化するたびに位置情報データが送信され、移動をやめるとデータの送信も止まるように、一定期間の位置情報データを一片に送信するのではなく、変化が起きる度にデータを送信していくのが特徴です。

リアクティブプログラミングでは、このような流れのことをデータストリームと呼びます。ListやCollectionといった一塊のデータの集合だけではなく、将来的に発生するであろうデータも含めてデータの集合体として扱います。

データを受け取ることに徹する

キーボード上で「hello」と打ち込む操作はどうでしょうか。

  1. h keyを打ち込む
  2. e keyを打ち込む
  3. l key を打ち込む
  4. l key を打ち込む
  5. o key を打ち込む

上記のように 1. の段階で、それ以降なにが打ち込まれるかに関わらず「何らかの key を押した」というイベントのデータが生成されたとみなすことができます。 key を複数回押した場合、その押した回数だけ「key を押した」というデータが生成されているということです。つまり、キーボード入力の一つ一つのキータッチにおいても、データストリームとして扱うことが可能です。

ここで重要なのは、リアクティブプログラミングはこのようなデータストリームから流れてくるデータに対して、受け取り手のロジックは受け取る度にデータを順次処理していく仕組みになっていることです。ロジック側が何らかの契機に自分からどんなイベントが発生したのかを能動的に取得していくのではなく、送らてきた(通知された)データを受け取る度に処理をするリアクティブなロジックになっています。

インクリメンタルサーチ

Image from Gyazo

Googleなどの検索窓に何らかのキーワードを打ち込むと、打ち込んでから何ミリ秒か後に「もしかして、これをお探しですか?」といくつかの候補を提案してくれる機能があります。これはインクリメンタルサーチと呼ばれ、あらゆる場面で目にする一般的なものです。

このインクリメンタルサーチに、リアクティブプログラミングを活用できます。先ほどの例のように、キーボードで何らかのキーワードを入力されたのと同時に検索窓のロジックへデータが送信(通知)されます。通知されたあと次の通知を待ちつつ、候補のキーワードを探しリストの形でUIに出力する処理が走ります。これがリアクティブプログラミングではない場合、「検索する」ボタンであったりキーボードで Enter キーを叩くなどしないとユーザーは検索結果を受け取ることができません。

検索窓にイベントリスナーを用意する実装との違い

今の説明だけでは、検索窓に「キーが入力されたこと」を監視するイベントリスナーをつくり、同様の処理をさせるロジックを書くことと何ら変わらないように思えます。しかし、「何が」データが発生した後の具体的な処理を担うのかが違ってきます。

イベントリスナーで監視する場合、検索窓(フォーム)がキーが入力されたことを検知し、フォーム自体が「フォームの下に検索候補のリストを表示させる」ことまでを担当します。

リアクティブプログラミングでは、検索窓が「フォームの下に検索候補のリストを表示させる」ことまで担当しません。あくまでも、検索窓は通知を送るだけに徹しており、その通知を受け取り検索候補を表示するのは「検索候補を表示するリスト」自身です。

結局、どんなメリットがあるか

  • どのロジックが何をするか、といった責任の影響範囲が明確になる
  • データが生まれる側は「データを通知する」という部分までが自身の責任になり、そのデータの受け取り手がそのデータをどのように使用するかは気にしなくて良い
  • 気にしなくてもいいので、通知を送ったあとはすぐに次のデータの監視へ徹することができる(受け取り手の処理が完了するのを待つ必要もない)
    • この性質が非同期処理と相性が良く、非同期処理にまつわるプログラムを容易に実装することができる

次の記事

azunobu.hatenablog.com

参考

RxJavaリアクティブプログラミング (CodeZine BOOKS)

RxJavaリアクティブプログラミング (CodeZine BOOKS)