はじめに
私がアプリを個人開発する中で、どのようなプロセスで開発を進めているか備忘録的な意味を込めて残しておこうと思います。
開発環境
言語:Dart
フレームワーク:Flutter
アーキテクチャ:Bloc
DB:Firestore
ディレクトリ構成
下記はlib配下のディレクトリ構成です。
主要なディレクトリを抜き出しています。
.
├── blocs
│ ├── hoge_bloc.dart
├── main.dart
├── models
│ ├── hoge_model.dart
├── repositories
│ ├── hoge_repository.dart
└── screens
└── hoge_screen.dart
開発プロセス
1: DB設計を行う
まずはDBにどのようなデータを保存するか設計します。
イメージしたDBを元にFirestoreにコレクションとドキュメントのダミーデータを入れておきます。
2: modelの作成
設計を元にmodelを作成します。
hoge_model.dart
class HogeModel {
HogeModel({
required this.fuga,
});
final int fuga;
factory HogeModel.fromDocument(DocumentSnapshot<Object?> doc) {
final Map<String, dynamic> data = doc.data() as Map<String, dynamic>;
return HogeModel(
fuga: data['fuga'],
);
}
Map<String, dynamic> toMap() {
return <String, dynamic>{
'fuga': fuga,
};
}
}
3: repositoryの作成
firestore↔BlocをつなぐためのAPIを作成します。
API作成時点でfirestoreとの接続確認を行っておくと良いと思います。
hoge_repository.dart
class HogeRepository {
final FirebaseFirestore _firestore = FirebaseFirestore.instance;
Future<void> addFuga(String fuga) async {
await _firestore.collection('fugaCollection').add(fuga.toMap());
}
Future<String?> fetchFuga() async {
final fugaDoc = await _firestore.collection('fugaCollection').doc('fugaDoc').get();
if (fugaDoc.exists) {
return HogeModel.fromDocument(fugaDoc);
}
return null;
}
}
4: blocの作成
Bloc↔screenをつなぐためのBlocを作成します。
hoge_bloc.dart
class HogeBloc extends Bloc<HogeEvent, HogeState> {
HogeBloc() : super(HogeState()) {
on<HogeEventFuga>((
HogeEventFuga event,
Emitter<HogeState> emit,
) async {
_hogeRepository.addFuga(
event.fuga,
);
});
}
final HogeRepository _hogeRepository = HogeRepository();
}
5: screenの作成
画面を作成します。
hoge_screen.dart
class HogePage extends StatelessWidget {
const HogePage({super.key});
@override
Widget build(BuildContext context) {
return BlocProvider<HogeBloc>(
create: (BuildContext context) => HogeBloc(),
child: const HogeScreen(),
);
}
}
class HogeScreen extends StatelessWidget {
const HogeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
'Hoge Screen',
),
),
body: BlocBuilder<HogeBloc, HogeState>(
builder: (BuildContext context, HogeState state) {
return TextButton(
child: const Text('button'),
onPressed: () {
context
.read<HogeBloc>()
.add(HogeEventFuga('piyo'));
},
);
},
),
);
}
}
最後に
私が紹介したのはデータの依存関係にしたがって依存元から実装していくやり方です。
逆にUIから実装していくのもありだと思います。
参考になる部分があれば幸いです。