LoginSignup
4
3

More than 5 years have passed since last update.

UnityのScript構成を考えてみる その5

Last updated at Posted at 2016-12-29

UnityのScript構成を考えてみる その4の続き。

≫ まとめ記事はこちら。

6. Factoryを利用したレイヤ間依存の疎結合化

さて前回までで表示とロジックの分離を押し進めた結果、MV(R)Pパターンに行きついた。

image.png

今回はここからさらに、Presenter、BusinessLogic、DataAccessの各レイヤの結合度合いを弱める努力をしてみたい。

前回まで、窓口クラスからデータアクセス層に属するクラスを呼ぶ際にnewを使っていた。

NumberMediator.cs
    public void Pow(int number)
    {
        Number = new Number(number);
        Number.Pow();

        var dao = new NumberFile("pow");
        dao.Save(Number);

        Calculated(Number.Value);
    }

この部分である。

    var dao = new NumberFile("pow");

だがしかし、このように書いていたのでは差し替えが難しい。例えば、「保存先はAPIサーバー経由のDBでお願いします。あ、でも、ローカルでUnityエディタ使ってるときだけはローカルPCに保存して下さい:grinning:」といった諸行無常の響きが感じられるリクエストが来た時に泣きを見る。
また、ユニットテストを行おうとしたときも、モックに差し替えるのが難しいため逐一ディスクのIOが走ってテストが遅くなるとか、MediatorのテストのはずなのになぜかDaoのテストをしているといったありがたくない効果を得てしまう。(こちらはMolesがなんとかしてくれるかもしれないが)

というわけで下記のようにFactoryを使ってdaoを呼び出すようにした。

NumberMediator.cs
    public void Pow(int number)
    {
        var Number = new Number(number);
        Number.Pow();

        var dao = NumberDaoFactory.Create("pow");
        dao.Save(Number);

        ReactNum.Value = Number.Value;
    }

こうすると、生成をFactory側で一括して取り扱えるため、差し替えが入っても変更が最小限で済む。現在のコードは下記のようになっているのだが、

NumberDaoFactory.cs
public class NumberDaoFactory
{
    public static INumberDao Create(string key)
    {
        return new NumberFile(key);
    }
}

たとえば次のように書き換えれば上述の愉快リクエストもさばくことができるはずだ。

NumberDaoFactory.cs
public class NumberDaoFactory
{
    public static INumberDao Create(string key)
    {
        if (UNITTEST) 
            return Mock(key);

        if (ENVIRONMENT == "local")
            return new NumberFile(key);
        } else {
            return new NumberApi(key);
        }
    }
}

また、Presenter側も同じく、Mediatorを呼び出すところをFactory経由にした。こちらは「とりあえずロジック部分はスタブで」が簡単にできるように、という意味合いが大きい。

NumberDaoFactory.cs抜粋
    private void Start()
    {
        // Modelの値の保持 
        NumberMediator = MediatorFactory.Create<NumberMediator>();

尚、このあたりのテクニックについてはC#実践開発手法を参考にした。

どこまでやるか

さていいことづくめのように思えるこの手法なのだが、副作用もある。やればやるほどinterfaceが大量に必要になるのだ。
これはこれで嫌なものなので、今回は各レイヤを接続する箇所に限定している。つまりPresenterがMediatorを呼ぶ個所と、BusinessLogicに属するクラスからDaoを呼ぶときである。

実際のコード

今回利用したサンプルはGithubの下記URLにアップしている。
https://github.com/nakatatsu/unity-sample

残る課題

今回課題と考えていた点はひととおり試すことができたように思う。そこで最後にふりかえりを兼ねて経緯をまとめたい。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3