少し時間がとれたので、iOS開発におけるアーキテクチャについて整理してみることにしました。
最近では、iOS開発におけるアーキテクチャについて語られる際には、MVVMとCleanアーキテクチャについて触れられることが多いように感じています。
そのため、MVVMとCleanアーキテクチャについて比較しながら理解を深めようとするのですが、用語が異なるため毎回混乱しています。
理由の一因として、MVVMのオブジェクトは役割分担が比較的明確に理解することができるのに対し、Cleanアーキテクチャの資料の多くは、概念に終始しているため実装例は様々な解釈が存在し、単純に比較することができないという点があると感じています。
個人的には、Cleanアーキテクチャの用語について馴染みがあまりない部分があるので、改めて用語についてまとめてみることにしました。
MVC、MVP、MVVM アーキテクチャ
このアーキテクチャは、それぞれ3階層構造で似ています。
View ←→ Controller ←→ Model
View ←→ Presenter ←→ Model
View ←→ ViewModel ←→ Model
Clean アーキテクチャ

【メリット】
- ビジネスロジックが明確になる
- FW、UI、DataStoreに依存しない
- テストが導入しやすい
【デメリット】
- 各層にインターフェイスが用意されるため、コード量が多くなる
ドメイン駆動開発(DDD)を意識して、ビジネスロジックをUIやFWから分離し、それぞれの階層ごとに役割と責務を分けたアーキテクチャ。
大別するとPresentation、Domain、Data Layer の3つの階層
Presentation Layer ←→ Domain Layer ←→ Data Layer
View ←→ Presenter ←→ UseCase(Translater、Model) ←→ Repository ←→ DataStore(Entity)
Presentation Layer
UIの表示やイベント ハンドリングを行う
ビジネスロジックは含まない
例えば、UseCase から取得したデータを成功、失敗に応じて処理し、View に通知する
Domain Layer
ビジネス ロジック、ビジネスルールを表す責務を負う
UseCase
どのようにデータを取得、生成するか実装する
例えば、Repository から取得したデータを加工し、ストリームに流す
Translater
UseCase で取得した Entity から View の表示に最適な Model を生成する
Repository
UseCase で取得したいデータの CRUD I/F を用意する
例えば、DataStore からデータを取得し、ストリームに流すなど
Data Layer
通信、永続化データを扱う
Data Store
複数の DataStore を扱う場合は、Factory パターンを用いて Repository がデータ種別を意識しない設計にすること
例えば、UserDefaults からデータを取得するなど
Entity
DataStore で扱うことができる性的なモデル
個人のまとめ
- VC、Modelが肥大化するのはプログラマが対処すべき
- Translaterの実装例がイメージしづらいのでサンプルを探したい
- 依存関係を一方向のみとし、相互依存を排除する
- 外部ライブラリを用いてアーキテクチャを実装することは避けたい
(DI、Repository を SwiftTask (Promiseライブラリ) でラップなど)
参考資料について
アーキテクチャの種類について効率よく知るには、「iOSアプリ設計パターン」が参考になりました。
クリーンアーキテクチャ完全に理解した
個人的には学術的な理解は不要で、まずはなんとなく使えるレベルでOKだと考えているので、少しボリュームがあると感じましたが、用語、概念についてざっと知りたい場合に良いドキュメントだと思います。
CleanArchitectureRxSwift
RxSwiftを用いたサンプルですが、Cleanアーキテクチャの概念を理解するには良いサンプルだと思います。

SwiftUI + Combine で MVVM & Clean Architecture な設計を考えてみた
Cleanアーキテクチャに、SwiftUI、Combineなどをどのように用いるのか?という点について、とても参考になりました。ボリュームも抑えられているので、サクッと理解できると思います。