🦴
【Flutter】小規模アプリ向けのディレクトリ構成考えてみた : Feature-first vs Screen-first
はじめに
Flutterでアプリを作るとき、ディレクトリ構成いろいろあって悩みますよね。😮💨
本記事では、MVVM+Riverpod を軽く紹介したうえで、代表的なディレクトリ構成パターン(Feature-first/Screen-first)を比較し、小規模アプリ向けのディレクトリ構成をご提案します。
この記事を読むと、プロジェクト規模に合わせた可読性・保守性・拡張性の視点で最適なフォルダ設計がわかるかなと思います。
技術スタック(MVVM+Riverpod)
※ ここでは技術スタックの紹介にとどめ、詳細実装は割愛します。
-
MVVM パターン
- Model(データ)/ViewModel(ビジネスロジック)/View(画面)に責務を分ける設計手法。
-
Riverpod
- 同期処理は
Notifier
+NotifierProvider
- 非同期処理は
AsyncNotifier
+AsyncNotifierProvider
- 同期処理は
Feature-first vs Screen-first
Feature-first
lib/
└── features/
├── auth/
│ ├── controllers/
│ ├── models/
│ ├── screens/
│ └── services/
└── home/
├── controllers/
├── models/
├── screens/
└── services/
-
features/◯◯/screens/...
と機能ごとに完結させるパターン。 - ✅ メリット
- 機能ごとに関連ファイルがまとまる ⇒ 変更時の影響範囲がフォルダ内で完結
- チーム分業しやすく、機能担当ごとに衝突が減る
- ⚠️ デメリット
- ディレクトリ階層が深くなる ⇒ パスが長く見づらい場合がある
- 小規模プロジェクトでは過剰に感じやすい
Screen-first
lib/
├── screens/
│ ├── login/
│ │ └── login_screen.dart
│ └── home/
│ ├── home_main.dart
│ ├── home_detail.dart
│ └── home_edit.dart
├── controllers/
├── models/
└── utils/
-
screens/◯◯/...
と画面ごとに一覧にするパターン。 - ✅ メリット
- フラット&シンプル ⇒ 初見でも全体像が把握しやすい
- 画面数が少ない小規模アプリに最適
- ⚠️ デメリット
- 機能横断的な変更時に複数箇所をまたぐ必要あり
- テスト設計がやや面倒
Feature-first vs Screen-firstの比較表
観点 | Feature-first 推奨 | Screen-first 推奨 |
---|---|---|
プロジェクト規模 | 中〜大規模、機能が複数かつ複雑 | 小規模、画面数が5〜10未満 |
チーム人数 | 複数チーム or 3人以上 | 1〜2人程度 |
拡張性/保守性重視 | 高 | 中 |
初期導入の学習コスト | やや高 | 低 |
テスト設計 | 機能単位で容易 | モジュール横断でやや面倒 |
UIデザイン主導 | 機能優先 | 画面優先 |
それを踏まえた小規模アプリ向けのおすすめディレクトリ構成
Feature-firstとScreen-firstのハイブリット型
lib/
├── core/
│ ├── constants.dart
│ ├── theme.dart
│ ├── utils.dart
│ └── widgets/
│ └── loading_indicator.dart
│
├── screens/
│ ├── auth/
│ │ ├── login_screen.dart
│ │ ├── login_controller.dart
│ │ └── login_model.dart
│ │
│ └── home/
│ ├── home_screen.dart
│ ├── home_controller.dart
│ ├── home_model.dart
│ └── home_widgets/
│ └── home_card.dart
│
└── utils/
├── auth_service.dart
├── firestore_service.dart
└── analytics_service.dart
フォルダの説明
- トップレベルフォルダは
core/
+screens/
+utils/
の3つで構成 - core/ に定数・テーマ・汎用Widgetをまとめ、重複を防止
- screens/ 配下には画面+その ViewModel・Model・小物 Widgetのみ
- utils/ に共通ロジック(Firebase/Analytics などの呼び出しや汎用ヘルパー)を集約
この構成だと、
- 画面構成は浅いネストで把握しやすく、
- ロジックやモデルの再利用性も確保でき、
- Shared Service 方式でFirebaseなどの外部連携も一箇所にまとめられる
などのメリットがあり、小規模アプリでも学習コストを抑えつつ、拡張の余地を残したバランスの良い設計になるかなと思います。
まとめ
- Feature-first vs Screen-firstの比較表
観点 | Feature-first 推奨 | Screen-first 推奨 |
---|---|---|
プロジェクト規模 | 中〜大規模、機能が複数かつ複雑 | 小規模、画面数が5〜10未満 |
チーム人数 | 複数チーム or 3人以上 | 1〜2人程度 |
拡張性/保守性重視 | 高 | 中 |
初期導入の学習コスト | やや高 | 低 |
テスト設計 | 機能単位で容易 | モジュール横断でやや面倒 |
UIデザイン主導 | 機能優先 | 画面優先 |
-
構成パターン選びのポイント
- 小規模&少人数 → Screen-first
- 中〜大規模&複数チーム → Feature-first
- 機能数は少ないが責務分離も欲しい → Feature-firstとScreen-firstのハイブリット型
- まずはハイブリッド型から始め、必要に応じて拡張
- ドキュメント化&チーム共有 で「なぜこの構成か」を明示し、全員が迷わない環境を整えましょう!
最後まで見ていただきありがとうございました!
参考になったなと思いましたらいいねしてくれると嬉しいです🙌
Discussion