UniRx の変数の監視は、ReactiveProperty より、ObserveEveryValueChanged を使うべき4つの理由

ReactiveProperty VS ObserveEveryValueChanged IT・プログラミング

※ 本記事にはプロモーションが含まれています。

こんにちは! ねこです。

Unity で、MVP アーキテクチャを利用して開発する場合、必ずと言っていいほど使われる UniRx。

こちら、基本的には、イベント処理的な利用がメインですが、値の変更も監視できます。

そのため、モデルのプロパティ(変数)の監視に利用されるケースも多いかと思います。

その際、ReactiveProperty を、下記のように利用する人も多いのではないでしょうか?

public class SampleRepository
{
    public ReadOnlyReactiveProperty<string> Sample => sample;
    private ReactiveProperty<string> sample = new ReactiveProperty<string>("サンプル");
}

public class SamplePresenter : MonoBehaviour
{
    public void Initialize(SampleRepository repository)
    {
        repository.Sample
            .Subscribe(value => 
            {
                Debug.Log("Change Value : " + value);
            })
            .AddTo(gameObject);
    }
}

もちろん、これで問題ないのですが、私は、プロパティ(変数)の監視は ObserveEveryValueChanged を勧めたいと思っています。

public class SampleRepository
{
    public string Sample {get; private set;}
}

public class SamplePresenter : MonoBehaviour
{
    public void Initialize(SampleRepository repository)
    {
        repository.ObserveEveryValueChanged(repository => repository.Sample)
            .Subscribe(value => 
            {
                Debug.Log("Change Value : " + value);
            })
            .AddTo(gameObject);
    }
}

その理由を以下に記載します。

ObserveEveryValueChanged を使うべき理由

結論 : 読みやすいコードになるから

結論をすごく簡単にいうと、ReactiveProperty よりも、ObserveEveryValueChanged のほうが、可読性の高いコードになるからです。

では、さらに理由を深堀っていきましょう。

理由1 : 英語として見た場合でも可読性が高くなる

例えば、Repository の、Sample という文字列を変更したい場合。

repository.ObserveEveryValueChanged(repository => repository.Sample)
    .Subscribe(RunMethod)
    .AddTo(gameObject);

と書かれてあると、Sample というプロパティ値の変更を購読してるんだと一目でわかります。

しかし、

repository.Sample
    .Subscribe(RunMethod)
    .AddTo(gameObject);

と書かれてた場合。

“Sample” というものが、このコードだけだと何者なのかがわからない可能性があります(特にルール無用のプロジェクトの場合)。

例えば、これがボタンクリックのようなイベント処理的なものか、値の変更なのか、はたまた・・・?

そのため、元のコードを見に行く必要が出てきたりして、コードを読む側の負担の増加につながります。

理由2 : イベント処理と変数の変更を明確に区別できる

上記だけだと、そんなややこしいことないんじゃないの? という感想を持たれる方もいると思います。

しかし、これにイベント処理的な振る舞いが混在すると、結構カオスになります。

ObserveEveryValueChanged で書いておくと、それがイベント処理的な記述になるため、全ての Observable をそのように解釈できるようになります。

もちろん、変数は、変数として区別して読むことができます。

これは、後でコードを読む側の心理的な負担の軽減にもつながりますし、メンテのしやすさに直結すると思います。

理由3 : プロパティに複雑な意味を持たせてしまう

上記の内容にも当てはまりますが、ReactiveProperty は、プロパティに Subject の機能を追加するため、便利な反面、やはり見た目複雑になってしまいます。

単一責任の原則とはちょっと違うかもしれませんが、なるべく単機能のみの提供が望ましいですよね。

理由4 : データベースとの接続が楽

あと、単純にですが、プレーンなプロパティやメンバ変数を扱ったほうが、Repository, Entity を扱う場合、楽なケースが多いです。

もちろん、データベースから、データを取得する時などは顕著にでるかと思います。

コンバートする手間やプレーンの変数と ReactiveProperty の使い分けを考えるよりは、全て変数で扱った方が楽ですよね。

最後に

基本チーム作業になる開発プロジェクト。やはり、後の人のや未来の自分(笑)にとって幸せになるコードを書きたいですよね。

コードの読みやすさについて、初学者むけに過去に記事も書いてます。

[sitecard subtitle=関連記事 url=/programming-needs-english-grammar/ target=]

では、いい Unity ライフを!