Comunicação entre BLoCs
Otimizando a Comunicação entre BLoCs no Flutter com o Padrão Mediator
Gerenciar múltiplos BLoCs em uma aplicação Flutter de grande porte pode se tornar caótico, especialmente quando esses BLoCs precisam se comunicar diretamente entre si. Essa abordagem pode levar a uma arquitetura complexa e difícil de testar.
O Problema da Comunicação Direta entre BLoCs
Imagine que você possui três BLoCs:
AuthBloc
: Responsável pela autenticação do usuário.ProfileBloc
: Carrega os dados do perfil do usuário.DataBloc
: Processa dados relacionados ao usuário.
Quando um usuário faz login, o AuthBloc
precisa informar ao ProfileBloc
para carregar o perfil e ao DataBloc
para buscar os dados relacionados. Se o AuthBloc
envia eventos diretamente para os outros dois, cria-se um acoplamento forte entre eles, dificultando testes isolados e a manutenção do código.
A Solução: O Padrão Mediator
O padrão Mediator oferece um hub central para coordenação. Cada BLoC foca apenas em sua própria lógica, enquanto o Mediator escuta e reage às mudanças de estado entre os BLoCs.
Benefícios:
- Elimina dependências diretas entre BLoCs.
- Facilita o gerenciamento de fluxos complexos.
- Arquitetura mais escalável e testável.
Implementando o Mediator
Passo 1: Criar o Mediator
Comece construindo um BlocMediator
simples que escuta as mudanças de estado e despacha eventos:
class BlocMediator {
final AuthBloc authBloc;
final ProfileBloc profileBloc;
final DataBloc dataBloc;
BlocMediator({
required this.authBloc,
required this.profileBloc,
required this.dataBloc,
}) {
authBloc.stream.listen((state) {
if (state is AuthSuccess) {
profileBloc.add(LoadProfileEvent());
dataBloc.add(FetchDataEvent());
}
});
}
void dispose() {
// Limpeza, se necessário
}
}
Aqui, o Mediator atua como um controlador de tráfego aéreo — não pilota os aviões, mas coordena seus movimentos.
Passo 2: Integrar o Mediator na Aplicação
Configure o Mediator em sua aplicação:
class LoginPage extends StatefulWidget {
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
late final BlocMediator _mediator;
@override
void didChangeDependencies() {
super.didChangeDependencies();
_mediator = BlocMediator(
authBloc: context.read<AuthBloc>(),
profileBloc: context.read<ProfileBloc>(),
dataBloc: context.read<DataBloc>(),
);
}
// Outros métodos, como build()
}
Cada BLoC continua realizando seu trabalho — sem saber da existência dos outros. Essa é a mágica do Mediator.
Passo 3: Lidando com Fluxos Mais Complexos
Se for necessário aguardar o carregamento do perfil antes de buscar os dados, basta estender a lógica do Mediator:
authBloc.stream.listen((state) async {
if (state is AuthSuccess) {
profileBloc.add(LoadProfileEvent());
await for (var profileState in profileBloc.stream) {
if (profileState is ProfileLoaded) {
dataBloc.add(FetchDataEvent());
break;
}
}
}
});
É aqui que o Mediator brilha — orquestrando fluxos assíncronos de forma limpa e centralizada.
Prós e Contras
Vantagens:
- Isolamento: Cada BLoC é independente.
- Escalabilidade: Fácil adicionar ou remover BLoCs.
- Testabilidade: É possível testar o Mediator isoladamente
Considerações:
- Mais Código: Uma camada adicional para manter.
- Complexidade Potencial: Com muitos BLoCs, o Mediator pode se tornar sobrecarregado.
No entanto, os benefícios superam os custos — especialmente em aplicações de médio a grande porte.
Comparação com Outras Abordagens
Abordagem | Prós | Contras |
---|---|---|
MultiBlocProvider | Configuração fácil | Não auxilia na sincronização entre BLoCs |
rxdart | Streams muito flexíveis | Curva de aprendizado mais acentuada |
Redux | Gerenciamento global de estado | Verboso, menos idiomático para Flutter |
Mediator | Coordenação centralizada, limpa | Requer configuração manual |
Conclusão
Se você está desenvolvendo uma aplicação Flutter com múltiplos BLoCs interdependentes, o padrão Mediator é uma opção que vale a pena considerar. Ele ajuda a desacoplar a lógica, escalar com confiança e manter sua arquitetura limpa. Se quiser saber mais sobre o padrão Mediator, consulte a aqui. Além disso, não se esqueça de conferir um simples exemplo em funcionamento aqui.
✎ Morpa