Escolar Documentos
Profissional Documentos
Cultura Documentos
Save
O objetivo desse post é explicar como aplicar Clean architecture a codebases react, tendo como
contêiner de estado Redux.
Trarei dois exemplos que são aplicáveis tanto para React como para React Native.
Código fonte
Caso o tutorial não seja relevante, você pode dar uma olhada direto no código.
eduardomoroni/react-clean-architecture
react-clean-architecture - A realistic approach to implement clean architecture
on react codebases Open in app Get started
github.com
Introdução
Como o objetivo deste post não é explicar os conceitos de clean architecture, falarei brevemente
sobre os conceitos que serão usados neste post. Caso já esteja familiarizado com os conceitos,
tu podes pular esta seção.
- How to write robust apps every time, using “The Clean Architecture”
Ao adotar Clean Architecture esta modelagem semelhante, porém com outros nomes e
ganhamos dois novos termos: Entidades e Interactors*.
Entidades
Entidades consiste nas regras de negócio que são universais, isto é independe da aplicação que
vai simular esta regra. Elas representam entidades que existem no domínio da aplicação.
A literatura também usa o termo caso de uso para se referir ao conceito, deixando o termo
Interactor para a implementação/instanciação de um caso de uso.
Open in app Get started
Adaptadores e Apresentadores
Componentes
É tudo aquilo que vai ser mostrado ao usuário. Mais especificamente aos Presentational
Components.
A regra de negócio é simples: O contador precisa ter um teto e um piso de valor, e esses
valores podem variar entre aplicações.
Entidade
counterEntity.ts
hosted with ❤ by GitHub view raw
Eu entendo que nem todo mundo gosta de mapear estruturas de dados como classe, o contador
poderia ser simplesmente um número ou uma estrutura de dados que melhor lhe convir.
Open in app Get started
Interactor
counterInteractor.ts
hosted with ❤ by GitHub view raw
Apesar de termos um monte de código para fazer uma coisa simples, temos o beneficio de termos
a nossa lógica de negócio completamente independente de agentes externos e conseguimos
configurar quais serão o teto e o piso durante a instanciação do interactor.
counterReducer.ts
hosted with ❤ by GitHub view raw
Resultado final
Open in app Get started
Usuários devem ser cadastrados com o Nome completo, e devem ser em lower case.
Durante o cadastro, precisa verificar se já existe um outro usuário com o mesmo email.
Entidades
Open in app Get started
Para resolver este problema mapeei as seguintes entidades: Email, Credencial e Usuário. Evitar
ter um post muito grande decidi não colocar as implementações aqui, mas tu podes conferir
neste LINK.
Interactor de Entrada
Para fazer o login de um usuário, precisamos de um serviço externo, normalmente uma API, que
vai verificar se o usuário existe ou não e depois ver se a senha esta correta para assim permitir a
entrada do usuário. O que torna o nosso interactor assíncrono e dependente de algo externo a
aplicação.
SignInInteractor.ts
hosted with ❤ by GitHub view raw
Aqui fizemos uso de inversão de dependência através de expor uma interface que recebe uma
credencial e retorna uma Promise que retornará um Usuário. Mais uma vez, o exemplo que
propus é simples com o intuito de mostrar o conceito, caso queira um exemplo um pouco mais
rebuscado tu podes conferir o Interactor de Cadastro.
SignInSaga.ts
hosted with ❤ by GitHub view raw
Mais uma vez o nosso adaptador, que neste caso é uma saga, simplesmente instancia o interactor
e chama a função relativa a ação desejada. Isso na realidade, aumenta a sensação que eu
costumo ter ao trabalhar com redux que é a quantidade de código boilerplate é gerado para fazer
algo relativamente simples. Porém estamos deixando nossa aplicação mais maleável para no dia
que tivermos coragem tirarmos de vez o redux da nossa aplicação.
Serviços
Na saga que acabamos de mostrar faz uso de uma implementação do LoginService que
chamamos de SampleService . Aqui entra um ponto interessante e que foi um dos pontos que me
fez acreditar em Arquitetura limpa para backends. Para a nossa lógica de negócio,
Open in app pouco importa
Get started
se estamos chamando uma stored procedure, fazendo uma query num banco mongo, chamando
uma API SOAP ou REST. Esses aspectos importam para fins operacionais e tecnológicos, e os
motivos para as tomadas de decisões podem ter mudado no meio do caminho. Deixar isso o mais
abstrato possível para as regras de negócio possibilita tomarmos decisões tecnológicas mais
voltadas a resultado, ao invés de voltado ao impacto negativo que essa decisão pode trazer ao
app em produção.
Resultado final
Conclusão
Provavelmente isso não vai ser o suficiente para te convencer que aumentar o grau de abstração
da sua aplicação vai te trazer benefícios a médio e longo prazo. Mas quando você estiver
Get started
Open in app
convencido e precisar de um exemplo para consolidar os seus estudos e organizar seu codebase
este post vai ser valioso. Pretendo compartilhar as motivações em outro post, quaisquer dúvidas
ou feedbacks são bem vindos.