UniRxを使ったMVPのサンプル

  • 8
    Like
  • 1
    Comment

あくまで参考程度に…

至極シンプルなこんなものを作るとして…

image

まずモデルを用意

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UniRx;

public class Model
{
    public ReactiveProperty<int> Count { get; private set; }

    public Model()
    {
        this.Count = new ReactiveProperty<int>();
    }

    public void Reset()
    {
        this.Count.Value = 0;
    }

    public void Increment()
    {
        ++this.Count.Value;
    }

    public void Decrement()
    {
        --this.Count.Value;
    }
}

ついでPresenterを用意

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UniRx;

public class Presenter : MonoBehaviour 
{
    public Button IncrementalButton;
    public Button DecrementalButton;

    public Text CountText;

    private Model _model;

    protected void Awake()
    {
        this._model = new Model();

        this.IncrementalButton.OnClickAsObservable()
            .Subscribe(_ => this._model.Increment())
            .AddTo(this);

        this.DecrementalButton.OnClickAsObservable()
            .Subscribe(_ => this._model.Decrement())
            .AddTo(this);

        this._model.Count
            .Subscribe(x => this.CountText.text = x.ToString())
            .AddTo(this);
    }

    protected void OnEnable()
    {
        this._model.Reset();
    }
}

あとは適当にシーンを作ってせっせとオブジェクトをD&D

image

で、巷で言われているアンチパターンは

Presenterに全部押し込めるパターンで、

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UniRx;

public class Presenter : MonoBehaviour 
{
    public Button IncrementalButton;
    public Button DecrementalButton;

    public Text CountText;

    private int _count;

    protected void Awake()
    {
        this.IncrementalButton.OnClickAsObservable()
            .Subscribe(_ =>
            { 
                this.CountText.text = (++this._count).ToString();
            })
            .AddTo(this);

        this.DecrementalButton.OnClickAsObservable()
            .Subscribe(_ =>
            { 
                this.CountText.text = (--this._count).ToString();
            })
            .AddTo(this);
    }

    protected void OnEnable()
    {
        this._count = 0;
        this.CountText.text = this._count.ToString();
    }
}

何でやばいかというと、以下を順に実装してみるとわかります。

  1. 正の数なら文字色を赤に、負の数なら青に、0なら白にする
  2. 自乗ボタンを追加
  3. OnEnable時にint.MinValue~int.MaxValueのランダムな数でリセットする
  4. -100以下なら-100に、100以上なら100にする機能を追加

これらが全部Presenterにのしかかると…
たとえメソッドを切り分けても、立派なナポリタンが出来そうですね、という感じです…

Modelに切り分けておくと、ちょっとは楽に機能追加できそうな気が、しませんか…?