Open4
iOSアプリ開発におけるベストなプロジェクトフォルダ構成の検討
全体的なフォルダ構成の検討
テクニカルロールごとにフォルダを分ける
概要
- 採用しているアーキテクチャに沿って、分ける
- MVVMなら、Models/Views/ViewModelsで分ける
AppName/
├ Models/
│ └ Function1Model.swift
│ └ Function2Model.swift
├ Views/
│ └ Function1.swift
│ └ Function2.swift
└ ViewModels/
│ └ Function1ViewModel.swift
│ └ Function2ViewModel.swift
Pros
- どんなアーキテクチャを採用しているのかわかりやすい
Cons
- 特定の機能で見た時に、その機能の他のロールがプロジェクトのどこにあるかわかりづらい
- 後からアーキテクチャを変えたい場合や、複数のアーキテクチャを採用したい場合に修正コストが高い
個人的な意見
「特定の機能で見た時に、その機能の他のロールがプロジェクトのどこにあるかわかりづらい」のデメリットが大きいので、個人的にはこのフォルダ構成には反対
参考
テクニカルロールごとにフォルダを分けた上で、機能ごとに分ける
概要
- 採用しているアーキテクチャに沿って分けて、その上で機能ごとにフォルダを分ける
- MVVMなら、Models/Views/ViewModelsで分ける
AppName/
├ Models/
│ └ Function1/
│ └ SomeModel.swift
│ └ Function2/
│ └ SomeModel2.swift
├ Views/
│ └ Function1/
│ └ SomeView.swift
│ └ Function2/
│ └ SomeView2.swift
└ ViewModels/
│ └ Function1/
│ └ SomeViewModel.swift
│ └ Function2/
│ └ SomeViewModel2.swift
Pros
- どんなアーキテクチャを採用しているのかわかりやすい
Cons
- 特定の機能で見た時に、その機能の他のロールがプロジェクトのどこにあるかわかりづらい
- 後からアーキテクチャを変えたい場合や、複数のアーキテクチャを採用したい場合に修正コストが高い
- 小規模アプリの場合、フォルダ構成が深いので逆に可読性が悪くなる
個人的な意見
「特定の機能で見た時に、その機能の他のロールがプロジェクトのどこにあるかわかりづらい」のデメリットが大きいので、個人的にはこのフォルダ構成には反対
機能ごとにフォルダを分ける
概要
- アプリが提供する機能ごとにフォルダを分ける
AppName/
├ Function1/
│ └ SomeView.swift
│ └ SomeViewModel.swift
│ └ SomeModel.swift
├ Function2/
│ └ SomeView.swift
│ └ SomeViewModel.swift
│ └ SomeModel.swift
├ Function3/
│ └ SomeView.swift
│ └ SomeViewModel.swift
│ └ SomeModel.swift
Pros
- アプリにどのような機能があるか、すぐにわかる
- 機能ごとに必要なファイルが一箇所に纏まっているので、修正がしやすい
- 機能ごとに異なるアーキテクチャを採用することも容易にできる(そもそも複数のアーキテクチャを採用すること自体は非推奨ではあるが、アーキテクチャの移行など過渡期にはあるあるだと思う)
Cons
- どんなアーキテクチャを使用しているか、ファイル名を見るまでわからない
- 中小規模なアプリの場合、機能ごとのフォルダ配下にswiftファイルが直置きされると、ファイル数がかなり多くなってしまい、可読性が低い
個人的な意見
- 「機能ごとに必要なファイルが一箇所に纏まっているので、修正がしやすい」というメリットがあるので、この方法は良いと思うが、かなりの小規模アプリ向けだと思う
機能ごとにフォルダを分けた上で、テクニカルロールごとに分ける
概要
- アプリが提供する機能ごとにフォルダを分け、その上で採用しているアーキテクチャごとに分ける
AppName/
├ Function1/
│ └ Views/
│ └ SomeView.swift
│ └ ViewModels/
│ └ SomeViewModel.swift
│ └ Models/
│ └ SomeModel.swift
├ Function2/
│ └ Views/
│ └ ViewModels/
│ └ Models/
├ Function3/
│ └ Views/
│ └ ViewModels/
│ └ Models/
Pros
- 「機能ごとにフォルダを分ける」と同じメリット
- フォルダ構成を見れば、どのようなアーキテクチャを採用しているかすぐにわかる
Cons
- 小規模なアプリの場合は、階層が深くなり、可読性が良くない
- 例えばViewsやViewModelsのフォルダに1ファイルしかないくらい小規模なアプリの場合、このフォルダの分け方はtoo muchだと思う
個人的な意見
- 上述した小規模アプリではここまでする必要はないかと思うが、中小規模アプリならこの構成でいいのではないか
共通で使用する実装の配置場所
Viewsの場合
- 例えばColorやButtonのスタイルなどの見た目に関わる場合
-
Common
>Appearances
のようなフォルダ階層を用意する?
-
- 例えばキーボードを閉じるなど挙動に関わる場合
- なんだろ、
Behaviors
とか?見たことないけど。。
- なんだろ、
Assetsの場合
- 例えば画像やlottieのアニメーションなど
-
Resources
のようなフォルダを用意する?
-
設定ファイルの場合
- 例えばInfo.plistやSetting.Bundleなど
- 以前は
SupportingFiles
というフォルダがデフォルトで作成されており、その中にInfo.plist
が配置されていたが、今はそれは無くなっている。無くなったのは何か理由があるはずなので、そうではないフォルダ構成がいいのではないだろうか
- 以前は
データ処理の場合
- 例えば複数箇所で共通で使用するネットワーク処理など
-
Networking
?
-
すべきではないこと(個人的意見)
-
Extensions
- 何かの拡張であることしか示していないので、そのフォルダ名は良くないと思っている
- ユーザーは拡張であることを知りたいのではなく、それを使って何ができるのかを知りたいはずなので、それがわかるフォルダ名にすべきではないだろうか
-
Utilities
- 人によって解釈が異なりすぎて何が配置されているかわからないので、より具体的なフォルダ名にして配置するべきではないだろうか
Viewsのフォルダ構成
フォルダ分けしない場合
Views/
├ ChildView1.swift
├ ChildView2.swift
├ ParentView.swift
Pros
- 小規模アプリでファイル数が少ない場合は、階層が浅くてみやすい
Cons
- ファイル名を工夫しない限り、どれが親Viewでどれが子Viewなのかわかりづらい
- 特にSwiftUIの場合、どのViewも拡張子が基本
.swift
になるので、なお分かりづらい- UIKitでViewをInterface Builderで実装する場合は、親がstoryboardで、子がxibなどになっていて拡張子を見れば比較的関係が掴みやすかったかもしれないが。
- 特にSwiftUIの場合、どのViewも拡張子が基本
親Viewと子Viewで分類を分ける場合
Views/
├ Components/
├ ChildView1.swift
├ ChildView2.swift
├ ParentView.swift
この機能内だけで再利用するアピアランスなどがある場合は、Viewsの直下にAppearances
やBehaviors
?的なフォルダを設けてもいいかもしれない。
Componentsよりは、Childrenの方が直接的でわかりやすいかも?
Material Design、Atomic Designを参考にして分けるのはどうなんだろう?いいのかな 🤔
Pros
- どれが親でどれが子Viewなのか分かりやすい
Cons
- 親Viewに対して、子Viewが1つしかないような場合はtoo muchかも
参考になる資料