【さちゃでもわかる】UniRx入門編①

## はじめに
以前書いた記事でUniRxの導入をしてみました．
本当はやりたいことがたくさんあったのですが書いているうちに脱線して行ってしまったので，何回かに分けてやっていけたらと思っています．
UniRxでよく出てくる言葉の説明をしていきたいと思います．
参考までに前回の記事を載せておきます．

参考：[【さちゃでもわかる】UniRx導入編](https://qiita.com/S4ch1mos/items/162767fa59296f74ced0)

## イベントの発行と購読
前回の記事でも述べましたが，UniRxのでは__イベント__という概念が鍵となっています．
Unityではよく`Button`のイベントに関数を紐付けたり，イベントシステムを使ってボタンを押した時の処理や，ポインターが乗った時などの処理を加えてきたと思います．
この時`Button`が行っているのがイベントの発行で，私たちが記述していたのがイベントの購読，つまり振る舞いの設定になります．
UniRxでもやることは変わりませんが，より自由になるので少し難しく感じるかもしれません．

というのも，今までイベントの発行はUnity独自のものを使っていたので，局所的な部分(ボタンのClick判定など)で使うことが主流でした．
しかし，UniRxではなんでもイベントにできます．Textの内容が変化したときや，`int`,`enum`,`string`,`独自クラス`，どんな変化もイベントとして扱うことができます．(これまでもUpdateで監視し続けたり，他にもいい方法はあると思いますが初学者の自分はよく知らないのですみません)
詳しくは何度も載せていますがこの辺が参考になると思います．

参考：[OnNextとSubscribe](https://qiita.com/toRisouP/items/2f1643e344c741dd94f8#2onnext%E3%81%A8subscribe)

## IObserverとIObservable
ここではUniRxを使う際基本となる2つのインターフェースについて紹介します．
それが`IObserver`と`IObservable`です．

###【IObserver】
IObserverインターフェースは、「イベントメッセージを発行できる」という振る舞いを定義したインターフェースです．
このインターフェースの定義は以下のようになっています．(引用元は[こちら](https://github.com/neuecc/UniRx/blob/master/Assets/Plugins/UniRx/Scripts/System/IObserver.cs))

``` C#
using System;

namespace UniRx
{
    public interface IObserver<T>
    {
        void OnCompleted();
        void OnError(Exception error);
        void OnNext(T value);
    }
}
```
つまり，IObserverインターフェースを継承したりなんなりすれば，`OnNext`,`OnCompleted`,`OnError`の3つのメソッドが定義されているので(ここら辺はインターフェースの部分が絡んでくるのでちょっとニュアンス歪んでいます)，これらを使ってイベントの各所でデータを流すことができます．

### 【IObservable】
IObservableインターフェースは、「イベントメッセージを購読できる」という振る舞いを定義したインターフェースです．
このインターフェースの定義は以下のようになっています．(引用元は[こちら](https://github.com/neuecc/UniRx/blob/master/Assets/Plugins/UniRx/Scripts/System/IObservable.cs))

``` C#
using System;

namespace UniRx
{
    public interface IObservable<T>
    {
        IDisposable Subscribe(IObserver<T> observer);
    }
}
```
こちらもIObservableインターフェースを継承なりなんなりすることで，`Subscribe`のメソッドが実行でき，イベントが発行された際に走らせる関数の登録ができます．

## Subject
UniRxの記事を調べていると`Subject`がめちゃくちゃ出てくると思います．
これは先ほど述べた，`IObserverインターフェース`と`IObservableインターフェース`の2つを実装しているクラスになります．
実際にSubjectの定義は以下のようになっています．

``` C#
using System;
using System.Collections.Generic;
using System.Text;
using UniRx.InternalUtil;

namespace UniRx 
{
    public sealed class Subject<T> : ISubject<T>, IDisposable, IOptimizedObservable<T>
    {
        object observerLock = new object();
        public void OnCompleted()
        {
            ...
        {
        ...
    }
}
```
長いので省略しますが大事なところは以下の部分です．

``` C#
public sealed class Subject<T> : ISubject<T>, IDisposable, IOptimizedObservable<T>
```
ここで継承している`ISubject<T>`の定義は以下のようになっています．

``` C#
namespace UniRx
{
    public interface ISubject<TSource, TResult> : IObserver<TSource>, IObservable<TResult>
    {
    }

    public interface ISubject<T> : ISubject<T, T>, IObserver<T>, IObservable<T>
    {
    }
}
```
これより，`ISubject<T>`が`IObserverインターフェース`と`IObservableインターフェース`を実装しているので，`ISubject<T>`を継承する`Subject`クラスも`IObserverインターフェース `と`IObservableインターフェース`を実装していることになります．
したがって，両方のメソッドが利用できます．

## OnNext/OnCompleted/OnError
IObserverインターフェース`に定義されていた3つのメソッドについてまとめると，
> 
OnNext : 通常イベントが発行されたときに通知されるメッセージ
OnError : ストリームの処理中で例外が発生したことを通知する
OnCompleted: ストリームが終了したことを通知する

となります．

## おわりに
最後まで読んでくださりありがとうございます．
書いてみて思ったのは，先人の方々はすごいなということです．
うまく言葉にできず参考に過去のQiitaを見ていたら，気付いたらほぼ内容としては同じものができてしまいました．
次回以降，もっと自分の言葉でまとめられるように精進していきます．

## 参考記事
- [UniRx入門 その1](https://qiita.com/toRisouP/items/2f1643e344c741dd94f8)
- [UniRx入門 その2](https://qiita.com/toRisouP/items/851087b4c990d87641e6)
- [作りながら理解するUniRx](https://qiita.com/mattak/items/106dfd0974653aa06fbc)