UniRxの始める前にざっくりと眺める


UniRxに関する素晴らしい記事はとてもたくさん出ている．UniRx入門シリーズ(https://qiita.com/toRisouP/items/00b8a5bb8e7b68e0686c )はUniRxを使う人は全員が目にした事があるだろう．とても分かりやすく書かれていて，いつ見ても感動する．
とても分かりやすい記事だけど，自分にはすこしもやもやが残っていた．Subject? Operator? Observer? それぞれについて整理してみた．

UniRxを始める前に大雑把に理解して置くことで理解が深まるだろうと思う．
本記事は概念的な面に触れただけで本質的に正しいとは限らない．**コードは登場しない**ため，ゆるっとふわっと理解してみたい人に読んでほしい．

# UniRxとは(ざっくりと)
UniRxとはイベント駆動型のリアクティブプログラミングを行うもの．

値が変更された，ボタンが押されたなどの「**イベント**」を別の場所に「**通知**」して，コンソール出力や関数実行などの「**処理**」を行う．この一連の流れをいい感じに記述するのがUniRxのライブラリとなっている．

![Notify.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/461d03c4-010f-0e27-dfaa-4dbc0e05a5d2.png)

プレイヤーがトゲに当たる(イベント)と，GameManagerに伝え(通知)，ゲームを終了する(処理)のように用いる．

# SubjectとOperatorとObserver

UniRxを理解する上で重要なのが「**Subject**」と「**Operator**」と「**Observer**」である．どの記事を見ても出てくるけど，あまりパッとしないものだった．
自分なりに考えてみた結果行き着いたのが「これらはインスタンス(人)である．」という事だった．これらはインスタンスとして生成されるのである．

つまりこういう人達だ．(それぞれがどんな役割を持っているかは後で説明する．)
![Character.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/3badf677-015f-9fa4-4e11-820371935952.png)

簡単に説明するとSubjectが通知を発行してOperatorが通知を加工して，Observerが処理を行う．通知を行う(言葉を発する)SubjectとOperatirには口が付いていて，処理を行うObserverには手が付いている．

１人ずつ役割を見てみよう．

# Observer

Observerは日本語で観察者を意味する．何かを監視している人だ．この日本語訳の通りObserverは値の変化やボタンなどの物を常に監視している．そして変化が起こった時に通知として受け取り処理を行う．

観察対象を指定してその変化を見る事ができる．寝ている猫を監視対象とする．
![Observe_down.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/3419048e-f893-d89e-b841-aecb496d0a42.png)

猫を監視対象としているので猫に変化が起きた時にObserverが処理を行う事ができる．今回は猫が起きたら旗をあげる(**処理**)を行なった．

![Observer_up.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/d3bc157a-5f8a-a43c-7010-c99172c3679e.png)

# Subject

Subjectを翻訳してみると最初に「主題」と出てくる．適切な訳し方は分からないが，「主人公」と捉えていいだろう．通知を発行する起点となる人がSubjectである．ObserverはSubjectを監視して通知があった時に処理を行うことがある．
SubjectはObserverに監視される側だ．主人公は誰かに監視されている．何か変化を起こしたら周りの人が処理を行う．
![Subject_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/f8232462-fd9a-a870-99b3-887987760496.png)

この右側のObserverはSubjectが「おはよう」と言ったら旗をあげ，他の言葉を発しても側はあげないという**処理**をつけておく．
Subjectは通知を発行する人なので，「おはよう」叫び通知を発行する．Observerは監視対象に変化が起こった事を通知として受け取る．「おはよう」という通知が発行された事を検知できる．

![Subject_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/436c10b8-11f4-1b14-c5d1-6f19b6cd0182.png)

逆に「おはよう」以外の通知が来た時には処理通り旗はあげないという処理を行う．

![Subject_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/1d12db79-401f-c3c1-64ea-91bf1c81ca1a.png)

SubjectはObserverに対して通知を何かを伝える人なのである．

# Operator

Operatorは日本語にすると「操作員」となる．今回の捜査対象は**通知**である．Operatorはたくさんの友達がいる．
操作対象は共通して**通知**だけど，人によっていろいろな処理を行う．Operator(https://qiita.com/toRisouP/items/0167ee5c41f79f55ad41 )はたくさんいて，行いたい処理によって使う人を選ぶ必要がある．
![Operator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/03fe156a-b70c-52c9-c6f9-94f17aabab56.png)

Operatorはつなぐ役割を持っているので，SubjectとObserverの間にいる．
日本語を英語に翻訳してくれるOperator-select-がいる場合の流れはこのようになる．

![Operator_flow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/7bef39b2-62b7-b062-af33-c2ff63672ce6.png)

通知を操作して加工するのがOperatorの役割である．
ObserverはSubjectを監視することがあるが，Operatorを監視していることもある．

# 組み合わせ

ここまでSubject，Operator,Observerそれぞれがどのような役割を担うか簡単に紹介した．実際に使う時にはこれらを組み合わせて使用していく．

- 1人のSubjectに対して監視するObserverの人数を増やす事ができる．

この場合Subjectが発行した通知に対して様々な処理を同時に行う事ができる．プレイヤーが敵と衝突したというイベントに対して，HPを減らす，SEを鳴らす，エフェクト表示すると言った複数の処理を行う事ができる．

![MultiObserver2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/d932719f-29f5-213e-d21c-a63a905a2d6e.png)

- Operatorを複数結合する

捜査員は通知を伝達して加工を重ねる事ができる．Operator-select-はデータを加工する捜査員でOperator-where-はデータを見て特定のデータだけ通過することができる．
データ(通知)に2を加える加えるOperator-select-とデータ(通知)が3の倍数のみを通すOperator-where-を繋げて34と39の通知を流すとObserverは36の時だけ通知を確認することができる．
![Flow_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/90ac3617-d0ec-48bf-38d1-592ef5cedd02.png)

![Fllow_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1113136/c580ff6f-8438-4d2a-4bc3-b310fcc084d6.png)

これらを組み合わせて色々なルートを作って通知を飛ばして加工して受け取って処理する事ができる．

# まとめ

Subject， Operator, Observerの役割が曖昧だったのをゆるっと整理してみた．大まかなイメージから入って置くと少し細かい処理に入った時にもこんがらなくて済むと思う．
実際にUniRxを使う時には世の中の天才たちの素晴らしい記事を参考にして欲しい．
UniRxはUnityで開発を行う上で本当に便利なライブラリなのでどんどん使用するといいだろう．