🙆

iOSアプリの設計を勉強しました

2021/10/01に公開

この二週間で、「iOSアプリ設計パターン入門」を読みながら、各アーキテクチャーで実装する、というのをやりました。
Githubのユーザー検索アプリを、Original MVC, Cocoa MVC, MVP, MVVM, Flux, VIPER, TCAの7種類で実装しました。
この記事はそのまとめ記事です。

実装まとめ

SwiftUIでMVCのiOSアプリをつくってみた
SwiftUIでMVPのiOSアプリをつくってみた
SwiftUIでMVVMのiOSアプリをつくってみた
SwiftUIでFluxのiOSアプリをつくってみた
SwiftUIでVIPERのiOSアプリをつくってみた
SwiftUIでTCAのiOSアプリをつくってみた

そもそもなぜ今設計を勉強しはじめたのか

iOSエンジニアとして、2019年からやってきて、今年が3年目のシーズンとなりました。
基本的には(Cocoa)MVCでずっと開発してきて、ViewControllerの肥大化に悩まされてきました。

個人開発の方は機能を絞りこんでるので肥大化を防げてるんですが、会社でやってるアプリがなかなかおデブになってました。
メインのViewControllerは今見てみたら、1,500行ありました。
修正の都度、切り出せるものは切り出しての1,500行なので、迫力があります。

これなんとかできないのかなーとずっと思ってて、設計を学ぶことでなんとかしようと思いました。

実務の中で出てきた疑問

あとコード書いていて、下記の問題でよく悩みました。

  • Viewの状態変更はViewに書くべきかControllerに書くべきか
  • Modelの状態変更はModelに書くべきかControllerに書くべきか

Cocoa MVCだと、たぶんControllerに書いちゃうで正解なんだと思うんですが、
ViewControllerの太り方が嫌すぎて、View/ModelにControllerっぽい処理を書いたこともありました。
それは正解なのか、間違ってるのか、自分でもよくわかりませんでした。
その辺の答えを、設計の勉強の中で欲しいなとも思いました。

ViewControllerの肥大化は必然

設計を勉強して分かったのは、Cocoa MVCの設計上、ViewControllerは絶対に肥大化する、ということです。
別に誰が悪い訳でもなく、そういう仕様、というだけでした。

アーキテクチャーの好み

「このアーキテクチャーを採用すれば全てが上手くいくよ」というものは当然ないので、物事にはメリットデメリットがあります。
というか最後は好みになるような気もします。

僕はシンプルで直感的なアーキテクチャーで、かつ費用対効果が高い、みたいなものが好きです。
勉強したアーキテクチャーでランキングをつけるとするなら、、こんな感じです。

  1. MVVM
  2. Original MVC
  3. VIPER
  4. その他

個人的にはMVVMぐらいが一番シンプルで費用対効果高い気がします。
Original MVCも良かったです。
というか全部のアーキテクチャーをよく見ると、Original MVCを再定義したり細分化したりしてるだけなんじゃないか、と思うときもありました。
開発環境によっては、Original MVCのView - Model間のPub/Sub関係の実現が難しくて、設計思想が実現できないケースも多かったんだと思いますが、
UIKitだとアレですが、SwiftUIを使うと簡単に実現できるので、正直Original MVCが自分的には一番キレイだった気がしています。

もっと言うと、SwiftUIだとControllerすら要らないかもしれません。MVだけでアプリつくれる気がします。
かつてのControllerの機能を、SwiftUIとCombineがやってくれるので。
スケールが大きくなったときにやっぱ調整役があったほうがいいですかね?
あと機能増やしていくと、Viewが肥大化して読みづらくなるのは起こると思うので、そこをどうするかですかね。
ミニマムな設計を考えてみたいです。

FluxとかVIPERとかはわけすぎな気がする

これは個人的な意見ですが、FluxとかVIPERとかはわけすぎじゃないかと感じました。
MVVMやOriginal MVCでキレイに書くことができれば、こんな細分化要らないんじゃないか、というのが僕の意見です。

「いや、開発者のスキルレベルや設計思想が違うから、チーム間で統一できることに意義があるんだよ」という意見もあろうかとは思うんですが、
個人的にはMVVMやOriginal MVCの構成で責務をキレイに切り分けられない人にFluxやVIPERで書かせても、混乱するだけなんじゃないかと思うんですよね……

皮肉な話で、「FluxやVIPERでちゃんと書けるエンジニアは、FluxやVIPERに従わなくてもキレイに責務をわけられる」と思うし、
「FluxやVIPERに従って欲しい設計力低めのエンジニアにはFluxやVIPERは学習コスト高すぎる」というのが現実じゃないかな、と思います。
まあでも、僕は設計方針ガチガチのプロジェクトに参加したことがないので、あくまで想像です。

宣言的UIがプレゼンテーションロジックの複雑性を吸収する

SwiftUI使って感じたことは、宣言的UIがプレゼンテーションロジックの複雑性を吸収することです。
なので、UIKitだとMVPって結構意味があったと思うんですが、SwiftUIだと?という感じです。
宣言的UIはパラダイムシフトだと思うので、まだ設計思想が追いついていない気がします。

Reactでも、かつてはReduxとセット販売みたいになっていましたが、
今では結局Reactだけが採用されて、Reduxは不採用、みたいなケースが多いと思います。

TCAがSwiftUIとの相性いいと聞いて期待していたんですが、実際書いてみたら思ってたのと違くて、そこは残念でした。

個人的な設計方針

個人的には、今後のiOS開発はSwiftUI x MVVMでやっていこうと思います。
大規模チーム開発だったら、VIPERを検討してもいいかな……
TCA(あるいはFlux, Redux)はメンバーがみんな大好きみたいな状況だったら付き合いますけど、自分からはあまり積極的に使おうとは思いません。

あとサンプルコードレベルなら、SwiftUI x MV(C)で書きますかね。

まとめ

というわけで設計話を終わります。
「iOSアプリ設計パターン入門」は2019年に何度も読んだ本なんですが、そのときは説明は理解しても、コードレベルで理解できていない状態でした。
当時の僕のプログラミングのレベルが低かったこともあって、結局腹落ちするまで理解できてませんでした。
2021年現在だとコードリーディング力も上がっており、所謂「解像度が高い」状態で読むことができました。

ただ読むだけだと、結局理論までで止まってしまうので、それだと机上の空論になってしまい、開発者としては意味がありませんでした。
設計自体は抽象的な議論なので、それを理解するのが大事だと勘違いしていましたが、実装と設計は結びついているので、
読んで「なるほどなるほど」で止まらずに、間違っていてもいいから、自分なりにサンプルアプリつくって実装してみることではじめて本当の意味でそのアーキテクチャーを理解することができた気がします。

今僕が各アーキテクチャーに感じているメリットも、今後実際に使っていく中でまた印象が変わるとは思うので、この記事に書いているアーキテクチャーの好き嫌いは、現時点での感覚になります。
時間が経ったり、経験積んだりで変わっていくとは思うんですが、今の時点ではこう思ったよ、というのを書かせていただきました。

Discussion