Because it prevents your presenter become a God object when it must handle UI logic and buniness logic too.
For example: a logout use case, you need to call API logout inside AuthenRepo
, unregister Firebase FCM token, close socket, and maybe clear some local data inside CartRepo
, UserRepo
, ... then imagine put all those things in Presenter, what a mess instead of create a LogoutUseCase
call to every repositories you need
And moreover, you can use it for many places, like when user press Logout button, when user login token is expired, ... just call LogoutUseCase
instead of copy code from this Presenter to another Presenter, also make is easy for you when you need to change something about logout requirement
Code example for Presenter is Bloc:
AuthBloc with UseCase:
class AuthBloc extends Bloc<AuthEvent, AuthState> {
AuthBloc(AuthState state) : super(state) {
on<AuthLogoutEvent>(_onLogout);
}
Future<void> _onLogout(
AuthLogoutEvent event,
Emitter<AuthState> emit,
) async {
await getIt<LogoutUseCase>().call(NoParams());
}
}
AuthBloc without UseCase:
class AuthBloc extends Bloc<AuthEvent, AuthState> {
AuthBloc(AuthState state) : super(state) {
on<AuthLogoutEvent>(_onLogout);
}
Future<void> _onLogout(
AuthLogoutEvent event,
Emitter<AuthState> emit,
) async {
await getIt<AuthRepo>().logout();
await FirebaseMessaging.instance.deleteToken();
await getIt<SocketRepo>().close();
await getIt<CartRepo>().clearData();
await getIt<UserRepo>().clearData();
// maybe more Repo need to call here :((
}
}
In your example above, it is only simple use case with only action getMarketWithSymbols()
, then I agree Usecase here is redundant, but for consistency, it should have and who know, in the future this UseCase need to scale up, then it will easy for you then.
await FirebaseMessaging.instance.deleteToken();
How would send that error message back the presentation layer? – Buonaparte