
BLoC의 아키텍처

BLoC의 코드 단축 과정
BLoC은 다음과 같이 3가지 레이어를 가진다.
하나의 Bloc은 오직 이벤트와 주입된 리포지토리(생성자를 통해 Bloc에게 주어진 리포지토리)를 통해서만 정보를 수신해야 한다.
그럼에도 불구하고 Bloc에서 다른 Bloc으로 반응해야하는 필요가 있다면, 두가지 옵션이 있다.
해당 문제를 프레젠테이션 레이어로 올린다.
class MyWidget extends StatelessWidget {
const MyWidget({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocListener<WeatherCubit, WeatherState>(
listener: (context, state) {
// When the first bloc's state changes, this will be called.
//
// Now we can add an event to the second bloc without it having to know about the first bloc.
BlocProvider.of<SecondBloc>(context).add(SecondBlocEvent());
},
child: TextButton(
child: const Text('Hello'),
onPressed: () {
BlocProvider.of<FirstBloc>(context).add(FirstBlocEvent());
},
),
);
}
}
해당 문제를 도메인 레이어로 내린다.
class AppIdeasRepository {
int _currentAppIdea = 0;
final List<String> _ideas = [
"Future prediction app that rewards you if you predict the next day's news",
'Dating app for fish that lets your aquarium occupants find true love',
'Social media app that pays you when your data is sold',
'JavaScript framework gambling app that lets you bet on the next big thing',
'Solitaire app that freezes before you can win',
];
Stream<String> productIdeas() async* {
while (true) {
yield _ideas[_currentAppIdea++ % _ideas.length];
await Future<void>.delayed(const Duration(minutes: 1));
}
}
}
class AppIdeaRankingBloc
extends Bloc<AppIdeaRankingEvent, AppIdeaRankingState> {
AppIdeaRankingBloc({required AppIdeasRepository appIdeasRepo})
: _appIdeasRepo = appIdeasRepo,
super(AppIdeaInitialRankingState()) {
on<AppIdeaStartRankingEvent>((event, emit) async {
// When we are told to start ranking app ideas, we will listen to the stream of app ideas and emit a state for each one.
await emit.forEach(
_appIdeasRepo.productIdeas(),
onData: (String idea) => AppIdeaRankingIdeaState(idea: idea),
);
});
}
final AppIdeasRepository _appIdeasRepo;
}
예시 사진