Clean Architecture: demonstração de um caso prático de refactoring total.
Tal como já foi demonstrado em artigos anteriores neste blogue,
a Clean Architecture é flexível o que permite substituir um componente
por outro
Será demonstrado um caso prático a partir de um simples ficheiro de código até a uma estrutura desacoplada.
Conceitos chave
Clean Architecture
Robert C.Martin criou a Clean Architecture que é um padrão
de design de software em que foco são as regras de negócio empresariais, mais
difíceis de mudar (Domain Layer) garantido o desacoplamento de fora para
dentro, isto é, tudo o que é externo deve ter um protocolo(Gateways, Repositories,
Presenters, .etc) que o implemente. Na Figura
1,
encontra-se representada o esquema padrão da Clean Architecture:
Figura 1- Clean Architecture
Fonte:
Cache
A cache é uma memória de acesso rápido que armazena dados
para uso futuro.
Esta memória pode-se encontrar em softwares como por exemplo
um browser de Internet
Cliente HTTP
O cliente HTTP serve-se do protocolo descrito no nome para conectar-se num serviço Web existente em rede. Uma pesquisa do Google trata-se de uma comunicação entre um cliente HTTP e um servidor através de métodos específicos.
Caso de estudo: Cliente em linha de comandos para resgatar filmes de um servidor externo
Para a criação deste cliente, utilizou-se o Node.js em
conjunto com algumas bibliotecas como por exemplo, o axios e a cache
Redis.
Considere o seguinte ficheiro da Figura
2:
Figura 2- index.js
É possível observar que existe algumas dependências externas,
como por exemplo, a API (Application Programming Interface) de filmes OpenMovieDatabase.
E se amanhã esta API deixar de funcionar e passar-se a chamar outro nome? Como
API é externa, não existe controlo do comportamento porque o código desta API pertence
a outra pessoa. No entanto, na Clean Architecture, não interessa como é
que a API funciona. Apenas terá de implementar um protocolo para resgatar os
filmes.
Outra dependência clara, por exemplo na linha 11, é a cache
em memória. E se amanhã quiséssemos criar um servidor HTTP que alimente uma
base de dados com filmes de várias fontes e quiséssemos remover a cache em memória
e substituir pelo Redis por exemplo?
Uma boa dica para
realizar um refactoring em algum código é fazermos a pergunta tal como no
parágrafo anterior com a frase “E se amanhã (…)?”. Isto ajuda bastante a descobrir
falhas de arquitetura no código.
Inicialmente, começou-se por definir o caso de uso SearchMovies (Figura 3):
Figura 3- Caso de uso SearchMovies
No construtor estão definidos os protocolos com as
dependências da fonte de dados e da cache.
Na função execute, a cache é verificada ou não dependendo da
sua existência. Se existir, a função this.cache.get() vai tentar buscar os
valores existentes. Se existir esses valores são retornados.
Em caso de não existir valores, ou não existir cache, os
valores são diretamente retornados da API de filmes linha 16
Após isso definiu-se o contrato da API de filmes (Figura 4):
Figura 4- Protocolo de comunicação com a OMDB
O construtor recebe a chave da API necessária para a realização de requests. Na linha 11 é feita a chamada a API de filmes usando a função axios.default.get().
Em caso de não exisitir dados será lançada uma exceção
indicando a indisponibilidade da API (linha 19).
De seguida desacoplou-se também a interface CLI das regras
de negócio, criando um adapter chamada NodeReadlineAdapter:
Figura
5- Adaptador da consola
A função init() cria a interface de comunicação e
inicializa a consola para leitura de dados realizando todo o processo de
negócio através da função this.inputText() da linha 35.
Figura 6- Cache em memória
Figura 7- Cache Redis
A classe da Figura 7 recebe uma conexão do Redis criada externamente
no início da aplicação. Pelo desconhecimento total do funcionamento do Redis,
optou-se em vez de armazenar em listas
Por fim criou-se a raiz da aplicação (Figura 8):
Figura 8- Composite Root
A função initApp conecta-se ao Redis e configura todas as dependências necessárias para aplicação funcionar sendo executada na linha 22.
Resultados:
Pesquisando o nome de alguns filmes, pode-se notar que a aplicação
foi buscar os dados à API externa (Figura 9)
:
Figura 9- Pesquisa de filmes sem cache
Ao fazer a pesquisa uma segunda vez pelo mesmo filme verificou-se que os dados foram resgatados da cache e não da API.
Figura
10- Pesquisa de filmes com cache
No entanto, algo que se poderia melhorar neste sistema seria
ao fim de algum tempo a cache ser limpa para os padrões iniciais.
Com este artigo, demonstrou-se novamente a flexibilidade da
Clean Architecture através do refactoring total de uma aplicação em
consola. A experiência com o Redis foi uma novidade para o autor do mesmo
Referências:
C.Martin, R. (2012). Clean Coder Blog. https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
Educative. (2024). Redis Data Types - Complete Guide to Redis. https://www.educative.io/courses/complete-guide-to-redis/redis-data-types
Leitão, M. (2016). Memória Cache.
Ravoof, S. (2023). O Que é Cache? Saiba mais Sobre Esta Tecnologia Comum e Complexa. https://kinsta.com/pt/blog/o-que-e-cache/
Teixeira, A. (2024). Migração de dados usando Clean Architecture. https://programandocomandre.blogspot.com/2024/02/migracao-de-dados-usando-clean.html