Arquitetura BLoC com Flutter

Fellipe Malta
5 min readJul 8, 2018

--

1. O que é a arquitetura BLoC?

A arquitetura BLoC (Business Logic Component) permite uma separação da logica de negócio da sua aplicação e da UI através do uso de Streams. Construímos toda a lógica de negócios com essa streams, o que nos permite o uso de bibliotecas Reactive como a RxDart.

Nós podemos fazer streams que se originam da arquitetura BLoC e podemos ter streams que se conectam da UI para a BLoC.

2. O que são streams?

Em suma, uma fonte de eventos assíncronos.

O conceito de streams é meio complicado, para isso, vamos usar uma analogia.

Vamos imaginar uma fábrica de queijo. Dentro da nossa fábrica, o que vamos produzir? Isso mesmo, queijos, no entanto, nossa fábrica é um pouco especial, quando disse que era uma fábrica que fazia queijos, é porque ela APENAS produz queijo, então, se alguém chegar e pedir outro tipo de alimento, desculpa, mas fazemos APENAS queijo .

Nossa fábrica não tem nenhum escritório remoto e se a pessoa quiser fazer um pedido, terá que ir diretamente e escrever um formulário solicitando um queijo, do TIPO, apenas. Então, nosso cliente preencheu o formulário, agora ela vai ter que entregar para o supervisor de formulário.

E qual o papel do nosso supervisor? Receber o formulário que foi escrito e levar para o interior da nossa fábrica para dar início ao processo. Então o pedido (request) é entregue ao supervisor e o mesmo envia-o para o inspetor de pedidos da fábrica.

Assim que a fábrica recebe o pedido, ele é analisado pelo inspetor. Ele vai coletar o tipo (type) de queijo que foi solicitado. O inspetor não se importa com mais nada, nem com o tamanho do queijo, nem para quem é, com nada, APENAS com o tipo do queijo. Uma vez que o inspetor tem o tipo, ele repassa para o cozinheiro.

Nosso cozinheiro irá analisar e vai dizer: “É queijo? Se sim, vou fazer, senão, não vou fazer e ainda vou emitir uma nota de erro para o cliente que solicitou e enviar para o ponto de coleta.” Então, não importa o que aconteça, nosso cliente terá que vir até a fábrica buscar seu queijo. Sim, nossa fábrica não faz entrega.

Caso o pedido tenha sido feito corretamente ou não, o pedido vai ser levado e deixado, no que eu posso chamar de: “Ponto de coleta”. Logo, é função do nosso cliente, ir até o ponto de coleta e ver se seu queijo está pronto ou não. Se por algum motivo o queijo não tenha sido feito, é por que o cliente errou quando preencheu o formulário e escreveu o TIPO (type) errado de alimento. Logo, para ele ter o seu queijo, terá que refazer o pedido (request), com o tipo (type) correto e esperar a resposta (response) no ponto de coleta.

Características da nossa fábrica de queijos.

1.1 Nossa fábrica recebe um ‘pedido’, processa, e então envia o pedido para outro ponto.

1.2 Nossa fábrica não é construída assim que o cliente aparece. Ela já está construída.

1.3 A fábrica passa muito tempo esperando para um pedido chegar. Assim que o pedido chega e é feito, nossa fábrica não desaparece logo após, ela é reutilizada para futuros pedidos.

1.4 Alguém tem que estar por perto esperando por um pedido chegar. Esse é o nosso ponto de partida (entry point) para o interior da fábrica.

1.5 Após o queijo ser feito, alguém tem que ir buscar ele. O queijo vai ser deixado no ponto de coleta, caso tenha sido feito e o cliente poderá levar seu queijo pra casa. Caso não, será deixado uma mensagem de erro solicitando que o cliente refaça seu pedido com o tipo correto de queijo.

Agora, vamos modelar nossa fábrica de queijos usando Dart.

Continuando, precisamos declarar nossa função main e começar o nosso código.

StreamController possui dois objetos adicionais já criados: sink (supervisor de entrega) e stream (inspetor de pedidos).

Sink: é a habilidade de adicionar novos dados para serem processados pela nossa stream. Comparando com nossa analogia, é o nosso supervisor de pedidos. O pedido não é enviado diretamente para a stream, apenas entregue ao sink para depois o próprio sink entregar a stream.

Stream: É a função que terá como incumbência, levar o pedido recebido até o cozinheiro da fábrica.

Pronto, agora que nosso supervisor de pedidos já trouxe o formulário para o inspetor, vamos referenciar nossa stream para que o pedido seja repassado ao cozinheiro:

Agora só precisamos modelar nosso cozinheiro e criarmos uma função para que ele possa preparar o queijo solicitado pelo cliente:

Em resumo…

Nosso inspetor de pedido, sendo mais específico, é a função do StreamController ‘sink.add()’. Ela recebe novos tipos de dados que serão levados e processados pela stream que criamos.

A stream recebe e processa esse pedido. A função ‘map’ da stream olha para o valor que recebe, processa, retorna o tipo do pedido e ai sim, leva para o cozinheiro.

O cozinheiro, vulgo ‘StreamTransformer’, observa o tipo que foi enviado, processa, prepara e então envia de volta para a stream.

A grande diferença entre as funções ‘map’ e ‘StreamTransformer’, é que na ‘map’ function temos apenas a proporção de 1:1 em termos de pedidos que podem ser recebidos e retornados para a stream. Enquanto com a ‘StreamTransformer’, nós recebemos um tipo de queijo, porém, podemos produzir mais. A função ‘sink.add()’ é mais flexível quanto a isso.

Esse ‘sink’ presente na função ‘controller.sink.add()’ serve para iniciarmos nosso processo. Enquanto o sink presente na função ‘handleData’ ele adiciona um valor logo abaixo da linha 47, que é aonde nosso cozinheiro atua. Então, se chamarmos a função ‘sink.add()’ dentro do nosso transformador, ele não inicia o processo, ele apenas adiciona um novo valor para o cozinheiro.

No fim, tudo vai para o posto de coleta (listen function), seja o queijo ou uma mensagem de erro do cozinheiro (transformer).

Nosso ponto de coleta retorna uma mensagem informando que seu queijo está pronto. E a função ‘onError’ é chamada quando se tem presente algum tipo de erro durante a produção e processamento, no nosso caso, uma string diferente do valor ‘cheese’.

Em termos práticos, essa arquitetura BLoC pode ser comparada com o padrão de projeto ‘factory method’.

--

--