フォルダ構成 - 1m-llc/Flutter-KtoK GitHub Wiki
考察
状態管理パターンが変わってフォルダ構成が変わらないように、Clean Architecture の状態管理のわかりやすさに重きを置いた案1がよい。
フォルダ構成パターン
状態管理(Provider+Change Notifier と Bloc)とClean Architectureに則ったフォルダ構成3案。
案1
Provider+ChangeNotifier
└ lib
└ core
├ constants ← 色やテキストなど
├ enums
├ models
├ providers
├ utils
└ viewmodels ← viewの管理とデータや機能を提供
├ screens
└ base_view_model.dart ← ※1 すべてのProviderを保持
└ main.dart
└ ui
├ dialogs
├ screens
└ shared
└ view_model_provider.dart ← ※2 ViewModelをビューに提供
└ main.dart
※1 base_view_model.dart BaseViewModelの役割は、アプリが必要とするすべてのProviderを保持することです。
class BaseViewModel extends ChangeNotifier {
final BuildContext context;
AuthenticationProvider authenticationProvider;
ResourcesProvider resourcesProvider;
ChatProvider chatProvider;
BaseViewModel({@required this.context}) {
authenticationProvider = Provider.of<AuthenticationProvider>(context);
resourcesProvider = Provider.of<ResourcesProvider>(context);
chatProvider = Provider.of<ChatProvider>(context);
}
}
※2 view_model_provider.dart このウィジェットの役割は、ViewModelをビューに提供することです。
class ViewModelProvider<T extends BaseViewModel> extends StatelessWidget {
final BaseViewModel model;
final Widget Function(T model) builder;
ViewModelProvider({@required this.builder, @required this.model});
@override
Widget build(BuildContext context) {
return ChangeNotifierProvider<T>(
create: (BuildContext context2) => model,
child: Consumer<T>(
builder: (BuildContext context, T value, Widget child) => builder(value),
),
);
}
}
Flutter Provider & ChangeNotifier Architecture Guide https://medium.com/@jgrandchavin/flutter-provider-changenotifier-architecture-guide-47ad05aa608e
案2
Blocパターンを参考にした構成
├── blocs ← bloc定義
├── resources
│ ├── api
│ └── models
│ └── enum
└── ui
├── common ← component widget
└── routes ← router
└── screens ← screen
└ lib
├ blocs
├ models
├ views
└ helpers
└ lib
├ bloc
├ models
├ pages
├ repositories
├ viewModels
└ main.dart
案3
Clean Architectureを参考にした構成
- 関心の分離
- 疎結合化
- モジュール分割
- 依存性の片方向性
- レイヤー分離
- プレゼンテーション層
- ドメイン層
- データ層
- コールフロー/データフローの一方通行化
root
├── app [プレゼンテーション層モジュール]
│ ├── pages => ページウィジェット
│ └── widget => ウィジェットコンポーネント
├── domain [ドメイン層モジュール]
│ ├── models => モデル
│ └── provider => Providerによる状態管理
├── repository [データ層モジュール]
│ ├── entitiy => エンティティ
│ └── repository => インターフェース
└───repository_cache [データ層(実装)モジュール]
└── repository => 実装 HTTP通信/ローカルキャッシュ
https://engineer.dena.com/posts/2020.03/techcon-app-2020-made-with-flutter-architecture/