Bloc (Business Logic Component)
Bloc(Business Logic Component)์ Flutter ๊ณต์ ํ์์ ์ง์ํ๋ ๊ฐ๋ ฅํ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค.
์ด๋ฒคํธ ๊ธฐ๋ฐ ์ํ ๊ด๋ฆฌ ๋ฐฉ์์ ์ฌ์ฉํ๋ฉฐ, ๋๊ท๋ชจ ํ๋ก์ ํธ์์ ๊ตฌ์กฐ์ ์ด๊ณ ์ ์ง๋ณด์๊ฐ ์ฌ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐ ์ ํฉํฉ๋๋ค.
Bloc์ ํต์ฌ ๊ฐ๋
Cubit vs Bloc
โข
Cubit: ๊ฐ๋จํ ์ํ ๊ด๋ฆฌ (๋จ์ผ ์ํ ๋ณ๊ฒฝ)
โข
Bloc: ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ํ ๊ด๋ฆฌ (์ฌ๋ฌ ์ด๋ฒคํธ ์ฒ๋ฆฌ ๊ฐ๋ฅ)
๊ตฌ๋ถ | Cubit | Bloc |
์ฌ์ฉ ๋ฐฉ์ | emit()์ผ๋ก ์ํ ๋ณ๊ฒฝ | ์ด๋ฒคํธ โ ์ํ ๋ณ๊ฒฝ |
์ฝ๋ ๋ณต์ก๋ | ||
์ด๋ฒคํธ ์ฒ๋ฆฌ | ||
์ฑ๋ฅ ์ต์ ํ | ||
์ถ์ฒ ์ฉ๋ | ๊ฐ๋จํ ์ํ ๊ด๋ฆฌ | ๋ณต์กํ ์ํ ๋ก์ง |
Bloc์ ์ฃผ์ ๊ธฐ๋ฅ๊ณผ ํน์ง
1. ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ํ ๊ด๋ฆฌ
โข
Bloc์ ์ฌ์ฉํ๋ฉด **์ฌ์ฉ์์ ์
๋ ฅ(์ด๋ฒคํธ)**์ ๋ฐ์ ์๋ก์ด ์ํ๋ก ๋ณ๊ฒฝ
โข
์ด๋ฒคํธ์ ์ํ๊ฐ ๋ถ๋ฆฌ๋์ด ํ
์คํธ๊ฐ ์ฉ์ด
2. ๊ณ ์ ํ ์ค๊ณ ํจํด
โข
Cubit โ ๋จ์ํ ์ํ ๋ณ๊ฒฝ (emit())
โข
Bloc โ ์ด๋ฒคํธ๋ฅผ ๋ฐ์ ์ํ๋ฅผ ๋ณ๊ฒฝ (on<Event>() ์ฌ์ฉ)
3. ๊ฐ๋ ฅํ ๋น๋๊ธฐ ์ฒ๋ฆฌ ์ง์
โข
async*์ Stream์ ํ์ฉํ์ฌ ๋น๋๊ธฐ ๋ก์ง์ ์ฝ๊ฒ ์ฒ๋ฆฌ ๊ฐ๋ฅ
โข
BlocObserver๋ก ์ ์ฒด ์ํ ๋ณํ๋ฅผ ์ถ์ ๊ฐ๋ฅ
4. ๋ฐ์ด๋ ์ฑ๋ฅ ์ต์ ํ
โข
BlocBuilder, BlocListener๋ฅผ ํ์ฉํ์ฌ ๋ถํ์ํ UI ๋ฆฌ๋น๋ ์ต์ํ
โข
BlocSelector๋ฅผ ์ฌ์ฉํ์ฌ ํน์ ์ํ ๋ณ๊ฒฝ๋ง ๊ฐ์ง ๊ฐ๋ฅ
Bloc ์ฝ๋ ์์ (Counter ์ฑ ์์ )
Cubit ์์ (๊ฐ๋จํ ์ํ ๊ด๋ฆฌ)
import 'package:flutter_bloc/flutter_bloc.dart';
// Cubit: ๋จ์ ์ํ ๊ด๋ฆฌ
class CounterCubit extends Cubit<int> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void decrement() => emit(state - 1);
}
Dart
๋ณต์ฌ
// UI์์ ์ฌ์ฉ
BlocBuilder<CounterCubit, int>(
builder: (context, count) {
return Text('$count');
},
);
Dart
๋ณต์ฌ
Bloc ์์ (์ด๋ฒคํธ ๊ธฐ๋ฐ ์ํ ๊ด๋ฆฌ)
import 'package:flutter_bloc/flutter_bloc.dart';
// ์ด๋ฒคํธ ์ ์
abstract class CounterEvent {}
class Increment extends CounterEvent {}
class Decrement extends CounterEvent {}
// Bloc ์ ์
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0) {
on<Increment>((event, emit) => emit(state + 1));
on<Decrement>((event, emit) => emit(state - 1));
}
}
Dart
๋ณต์ฌ
// UI์์ ์ฌ์ฉ
BlocBuilder<CounterBloc, int>(
builder: (context, count) {
return Column(
children: [
Text('$count'),
ElevatedButton(
onPressed: () => context.read<CounterBloc>().add(Increment()),
child: Text("์ฆ๊ฐ"),
),
],
);
},
);
Dart
๋ณต์ฌ
Bloc ํจํด์ ํต์ฌ ๊ตฌ์ฑ ์์
๊ตฌ์ฑ ์์ | ์ค๋ช
|
Bloc | ์ํ๋ฅผ ๋ณ๊ฒฝํ๋ ํต์ฌ ํด๋์ค |
Event | ์ฌ์ฉ์ ์
๋ ฅ์ ์ ์ํ๋ ์ด๋ฒคํธ |
State | ํ์ฌ ์ฑ์ ์ํ |
BlocBuilder | ์ํ ๋ณ๊ฒฝ์ ๊ฐ์งํ์ฌ UI ์
๋ฐ์ดํธ |
BlocListener | ์ํ ๋ณ๊ฒฝ ๊ฐ์ง ํ ํน์ ๋ก์ง ์คํ |
BlocProvider | Bloc ์ธ์คํด์ค๋ฅผ ์ ๊ณตํ๋ ์์ ฏ |
Bloc vs ๋ค๋ฅธ ์ํ๊ด๋ฆฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋น๊ต
๊ธฐ๋ฅ | Bloc | Riverpod | GetX | Provider |
์ํ ๊ด๋ฆฌ ๋ฐฉ์ | ์ด๋ฒคํธ ๊ธฐ๋ฐ | StateNotifier | obs | ChangeNotifier |
๋น๋๊ธฐ ์ง์ | ||||
์์กด์ฑ ๊ด๋ฆฌ (DI) | ||||
์ฑ๋ฅ ์ต์ ํ | ||||
ํ
์คํธ ์ฉ์ด์ฑ |
โข
๋๊ท๋ชจ ์ฑ์์ Bloc์ ์ฌ์ฉํ๋ฉด ๊ตฌ์กฐ์ ์ด๊ณ ์ ์ง๋ณด์ํ๊ธฐ ์ฌ์
โข
์คยท์๊ท๋ชจ ์ฑ์ด๋ผ๋ฉด **Riverpod ๋๋ GetX*๊ฐ ๋ ๊ฐํธ
Bloc์ด ์ ํฉํ ๊ฒฝ์ฐ
์ํฉ | Bloc ์ฌ์ฉ ์ฌ๋ถ |
๊ฒฐ๋ก : ์ธ์ Bloc์ ์จ์ผ ํ ๊น?
โข
๋๊ท๋ชจ ํ๋ก์ ํธ์์ ์์ ์ ์ธ ์ํ ๊ด๋ฆฌ๊ฐ ํ์ํ ๋
โข
์ด๋ฒคํธ ๊ธฐ๋ฐ ๊ตฌ์กฐ๋ก ์ํ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์ถ์ ๋
โข
ํ ๊ฐ๋ฐ์์ ๋ช
ํํ ์ฝ๋ ๊ตฌ์กฐ๋ฅผ ์ ์งํ๊ณ ์ถ์ ๋