読者です 読者をやめる 読者になる 読者になる

Timers Tech Blog

カップル専用アプリ「Pairy」, 子育て夫婦アプリ「Famm」を運営している Timers inc. の公式Tech Blogです。

何故TimersのiOSチームではモダンアーキテクチャを採用しないのか

Apple iOS Xcode Swift Architecture

f:id:timers-tech:20170120100614p:plain

明けましておめでとうございます!本年もよろしくお願いします! 年末から猫を飼い始めてなるべく早く家に帰りたいかっくんです。

最近iOS界隈ではMVC以外のアーキテクチャが流行ってますね。
ベースは昔からあるMVCですが、MVPやMVVM、VIPER、Clean Architecture等など...
どれもメリット/デメリットあるかと思いますが、弊社のiOSチームではどれも採用せずに昔からのMVCでプロジェクトを進めています。

何故他のアーキテクチャを採用しないのか

一言で言うと学習コストが高いのが大きいです。が、それだけでも無いので細かく記述したいと思います。

学習コスト

先述しましたが今と違うことをしようとするとどうしても学習コストが高くなります。
また、一人ならいいですが複数人いる場合はチーム内の皆も同じく学習する必要があります。
個々人のスキルに差が合ったり、メンバー間で認識がずれたりしていると、そこで無駄なコミュニケーションを生むことになります。
チームで議論していて、たまにアーキテクチャに関する話も出るのですが、「皆が学習するのってやっぱり大変だよね。それなら基本は変えずに綺麗なコードを書く事に専念した方がいいのでは」という結論になりました。
現フェーズではアプリのクオリティ向上により時間を使うべきという意見もあります。

本当にiOSに向いてる?

MVP、MVVM、Clean ArchitectureなんかはiOS以外のプラットフォームから来た様に認識しています。
(VIPERは検索するとiOS関連の事ばかり引っかかるのでiOSスタートなんですかね?)
対してiOSMVCでは画面を基本的に UIViewController をベースに作るので、ビューの操作、イベントハンドリング、画面遷移、モデルの更新等全てを UIViewController が担う事になります。
仕様変更やビューの追加等が増えるとどうなるか。

FatViewController

アーキテクチャの話をすると必ず出てくるこのワード FatViewController
UIViewController 内にコードを書きすぎて肥大化してしまう事を表す言葉ですね。
弊社のiOSチームで議論した時に「FatViewController」でも良いんじゃないか?という結論に達しました。
1つのファイルに全てが書かれているので色んなファイルを行き来する必要が無い、ちゃんとコメント(ドキュメントコメントやマークコメント等)が書いてあればコードを見る時もすぐ理解出来るんじゃないか?という事ですね。
分ける必要がある時は分ければ良いし、必要があればIDEの機能でコードまでジャンプ出来るしファイルをわけても大きくは困らない。

余談ですが、ファイルを分割し過ぎるとSwiftのビルド遅くなるというデメリットもあったりするのでファイルをたくさん分割する事って本当に必要なの?と自問してみても良いかもしれません。

本当にMVCで疲弊しないのか?

勿論、必ず UIViewController が全てを担わなければいけないわけではなく、最低限の役割分担はしています。
例えば、僕は最近 UIViewController 内に router: SomeRouter を持たせる様な書き方を意識しています。

struct SomeRouter {
    weak var viewController: UIViewController?

    func showRegistrationView() {
        let registrationViewController = RegistrationViewController()
        self.viewController?.navigationController?.pushViewController(registrationViewController, animated: true)
    }
}

class ViewController: UIViewController {
    lazy var router: SomeRouter = SomeRouter(viewController: self)

    @IBAction func tap(registButton: UIButton) {
        router.showRegistrationView()
    }
}

他のアーキテクチャを参考に最低限の画面遷移を UIViewController から切り離して作る様にしてみました。

また、アーキテクチャのキーワードとしてもう一つ上がるのが 疎結合 ですね。
これはなるべく取り入れたいなと思っていて、画面遷移の間に新たに画面が加わる場合等に密結合だと辛い場面は容易に想像出来るので、画面や class 等はそれぞれをコンポーネントの様に扱う事を意識しています。

また、Closure は積極的に使って、関連のある処理は近くに記述するという事も意識しています。

ライブラリのバージョンアップ

MVVMアーキテクチャを採用している場合、RxSwift等のライブラリを使っている事が多いかと思います。
iOSプログラミング言語としてもメジャーになりつつあるSwiftも、3.0で破壊的なバージョンアップを行いました。
Swiftの場合、言語のバージョンアップ -> ライブラリのバージョンアップ -> アプリのバージョンアップという様に、言語とライブラリのバージョンアップを待たないと本質的な作業に着手出来なくなってしまいます。
RxSwiftの様なメジャーなライブラリの場合は、放置される心配は無いかもしれませんが、個人で作っている様なマイクロライブラリはアップデートすらされない可能性があります。

本当に外部ライブラリに依存しちゃって大丈夫でしょうか?

Timersの思想

Timersでリリースしているアプリは ミニマル を思想に掲げています。
1つの画面で出来る事をなるべく少なくしよう、どんなにユーザーが便利になろうと、画面に1つボタンを増やす事がどれだけ必要なのかを議論しようという文化があります。
ユーザーに重要な選択を迫る場合は2つ以上の選択肢は出さないというルールもあります。
この文化のお陰で1つの画面にやたらと機能が追加される事はありません。
1つの画面に対して処理が多くならないという事も、他のアーキテクチャを導入しないで済んでいる事に繋がっているのかもしれません。

まとめ

決して誤解して欲しくない点として、TimersのiOSチームのメンバーはMVCしか知らないというわけではありません。個人的にRxSwiftを使っているメンバーもいますしClean Architectureを勉強している人もいるかもしれません。
将来的にどれかのアーキテクチャを採用する可能性も否定は出来ませんが、あくまでも今はチームの方針としてMVC以外のアーキテクチャは採用していないよ、というお話でした。


また、弊社では、子育て家族アプリFamm、カップル専用アプリPairyを運営しており、現在エンジニアを積極採用中です! 急成長中のサービスの技術の話を少しでも聞いてみたい方、スタートアップで働きたい方など、是非お気軽にご連絡ください! 採用HP : http://timers-inc.com/engineerings