水無月の余韻 開発Sc.

プログラミング関連の雑記

iOS版の加賀ゆびぬきシミュレータを書き換えているはなし (自分メモ)

(今日は自分メモなので、文章は素です。)

いろいろ集ってきた要望を取り入れて、機能を増やすために、ひさしぶりに加賀ゆびぬきシミュレータをがりがりと書いている。 今回、大きく書き換えをしているので、その経過を残したい。

課題

このアプリのアーキテクチャはほぼMVCである。 そして一番重いのが、いい感じにシミュレート結果を描画する機能である。

もともとEntityとModelがべったりくっついていて、配列の二重管理が発生していたために問題が多かった。 まずは、そこを解消した。

次に、Modelに描画のためのプロパティと処理がかなり含まれていて見通しが悪いのが問題になっていた。 ここはテストが書きにくく、複数の責任を持っていると感じていたところである。

はやりのクリーンアーキテクチャの勉強をしていたのもあり、全面的に書き換えるという妄想も持ったが、問題になっているところだけエッセンスをもらうことにした。 クリーンアーキテクチャでは、ModelをViewのためのViewModelへ変換する層がある。 描画のために必要な情報だけを含むViewModelを作れば、Modelのごちゃごちゃを減らせそうであると考えた。

したがって、今回は、Modelの見通しの悪さを解消するために、描画のためのModelを新たに作ることにした。 データ編集のためのModelと、描画のためのModelを分けるのである。 描画のためのModelはViewModelと呼ぶことにした。

実装

これまでの構造では、データの流れは以下のようになっていて、ViewControllerはModelを書き換えながら描画をしていた。 描画のためのプロパティを Model が持っていたのである。

ValueObject -> Model <--> ViewController

新しい構造では、データの流れが一方通行になって、ViewControllerはViewModelを参照するが、書き換えをしないで描画できるようになった。 描画のための一時的な状態は、ViewController内で完結した。

ValueObject -> Model -> (translater) -> ViewModel -> ViewController

ModelからViewModelへの変換は、translaterで行うことにした。 ViewModelは、状態が変わらないオブジェクトになり、ViewControlelr内の描画処理も複雑さが減った。 ViewController内の処理が簡潔になったことで、描画の不具合は、ほぼModelからViewModelへの変換部分の問題であると限定できるようになった。 ModelからViewModelへの変換のテストを書けるようになったので、問題の検証が容易になった。

その後

現在は、既存機能の書き換えが終わって、予定していた機能追加ができる状態に辿りついたところである。 リリースまではまだ少し時間がかかる。

手続き構造が変わったこと

(ここはコードなしで伝えるのがむつかしかったので、自分向けです。)

今回の書き換えで、手作業をそのままコードにしたような手続きそのままの実装が消えた。

これまでは、手作業に準じていたので、割と条件判断が複雑だった。 人間の作業は、意外に複雑なようだ。

// 描画の疑似コード
- 手順があるだけ繰り返す
   - 糸の色を選択
   - 一段終わるまで繰り返す
      - 一針分すすめる(描画) → 段を変えるべきか?

描画の部分だけで言えば、条件判断が減った。

// 描画の疑似コード
- 描画設定があるだけ繰り返す
   - 一段分の設定を取り出す (色、方向、位置を持つ)
   - 設定に従って描画する

複雑な分岐は、ModelからViewModelへの変換部分へ移動したが、考え方自体が大きくかわった。 行ってみないとわからない、という状態から、未来が予測可能になったような大きな変化だと思った。

// 変換の疑似コード
- 手順があるだけ繰り返す
   - その手順で刺す回数を計算する
   - 糸の色の段数を決める
   - 刺す回数分くりかえす
      - 描画設定をつくる (決めた段数に応じて色を変える)