ReactiveExtensionsへの理解のメモ

何故最近Rxについて調べているのか
個人的な動機

最近は動くことより、読みやすい設計、変更に強い設計などに興味がある。
その中で、Reactive Extensionを使ったReactive Programmingに触れる機会があったので、
勉強してみた。

# ゴール

正直内容の抽象度が高すぎて理解が難しいと思うので、以下を覚えてもらえれば良い。

* ReactiveProgrammingという概念が存在すること
* ReactiveExtensionsというライブラリが存在し、それは特定言語だけではなく様々な言語に存在すること
* ReactiveExtensionsは非同期処理を扱う時に便利であること

# ReactiveExtensionsとは

ReactiveProgrammingを実現するためのデザインとライブラリ。
Java/Kotlin/JavaScript/C#/Scala/Python/Swift etc etc
主に非同期な処理を解決するためのフレームワーク

## 非同期処理とは
* ユーザーからの画面入力
* ボタンタッチ
* HTTPリクエスト/レスポンス
* 現在地取得センサー
* ファイルアクセス
etc

## 既存の問題解決手法
* delegateパターン(コールバック)
 相手に終わったらこれを呼び出してね、とお願いする
* Observerパターン
 イベント発信側と受信側を用意し、非同期処理が完了した時点で受信側にそれを通知するというデザインパターン
(GoFデザインパターンなどを参照)
RxはObserverパターンをより拡張(隠蔽)したものである。

ReactiveProgrammingはデザインパターンや思想なので、言語を跨いで利用できる。
実際、RxJSで利用していたのでRxSwiftは簡単に扱えた。


# ReactiveProgrammingのパラダイム

1. 宣言的な記法(どうするではなく、どうなっているを記載する)
2. データの時系列リスト化
 * 宣言的プログラミングや関数型プログラミングなど似たような概念が結構あって、僕もまだ区別できていない。

## 反応的(宣言的)

反応的に変化しない命令的な場合

A = 1
B = A * 3
A = 2

A-> 1,B -> 3

反応的に変化する宣言的な場合
A = 1
B = A * 3
A = 2

A -> 1, B -> 6 <— AとBは *3 という関係性が定義されているので、Aの変更がBにまで反映する。

B = A * 3
BとAは*3の関係性を持つ。ここで定義されたのは何をするのか、ではなくどうなっているのか?である

ExcelなどはReactiveと言える。プログラムとしては奇妙だが、動作自体は直感的とも言える。
内部的にはAの変更を検知して、Bに反映されているのだが、その部分を隠蔽してくれるのがRxとも言える。


## 非同期イベントを全てストリーム(時系列リスト)として考える
関係性と考えると、その関係性への入力は「状態」とみなすことができる。
そして、状態というのは時系列に変化する(例えばチェックボックスやテキストボックスも状態と考えることができる)

全てのものがどういう状態の場合、どうなるのか、ということを定義し、
そこに時系列的なデータを入力すると、データや画面が入力に応じてパチパチと変わっていくよね?
ということである。
(すべてのセルに関数が埋め込まれており、ある一つのセルが時系列に応じて変化していく様を想像してほしい)

## そう考えると何が良いのか?

抽象度が高すぎて難しいかもなので、実際のコードを見た方が早いかも。

1. テストがしやすくなる、動作が理解しやすい

手続き型で“BにはAに3をかけたものを入れる”というコードを書いたときのテストは、”BがAの3倍であること”を確認するはずである。これは解説すると、”BにAに3をかけたものを入れた意図は、BがAの3倍であるようにしたいから”という意図を表現したいからである。

宣言型の場合、”BはAの3倍である”と書いており、意図もなく書いた通りである。もう定義の時点で、テストの目的の一つである意図を表現することができているのである。

つまり、テストとはそもそも宣言的なものであるため、宣言的に書かれるとテストがしやすくなるのである。
また、コードは振る舞いそのものなので、振る舞いは当然理解しやすい

2. すべてのデータが変換可能になる
先の例だと、A -> [1,2,3]となったときB->[3,6,9]となる。これは一つのストリームが別のストリームに変換できたことになる。
チェックボックスがクリック何度かクリックされると、そのたびテキストボックスに「使用可」「使用不可」と表示される流れを考える。
[false, true, false] -> [使用不可,使用可,使用不可]というストリーム変換と理解できる。
このように抽象度を引き上げると、全てのものに関係性を記述することが可能になる。

3. 組み合わせられる
"CはAの偶数判定の結果である”という定義があったとする、
A[1,2,3] -> C{false, true, false]となる
当然このCというストリームは2.のテキストボックスの表示に利用することができる。

# memo
* 状態は変化するが、振る舞いは変化しない
* 変化するものを引数にし、変化しないものを固定させる。
→状態を変数化、振る舞いを定数化させる。
→また、状態は時系列に変化するため、状態をシーケンシャルなリストで表現する

参考資料
https://blog.mmmcorp.co.jp/blog/2016/07/22/why-rx/