Arquitetura para iniciantes — Parte 2

Aline Souza
Aline Souza
Published in
4 min readJun 30, 2021

Agora que já entendemos o que é essa tal arquitetura que tanto falam na parte 1 da série "Arquitetura para iniciantes" (se você não leu, recomendo fortemente que leia antes de prosseguir), vamos começar a nos aprofundar nos detalhes arquiteturais.

Photo by Christina @ wocintechchat.com on Unsplash

Este artigo usará como base o projeto BaseDroid, disponível neste repositório. O ideal é que o tenha em sua máquina para posterior consulta e melhor entendimento do artigo.

Clean Architecture

Depois de entender a importância de ter uma arquitetura bem definida (lembra da casa que precisava de mais quartos?), foi necessário escolher dentre tantas opções (clean architeture, onion architecture, hexagonal architecture, entre outras) qual se encaixaria melhor em nossas necessidades.

E foi nesse momento que decidi utilizar o Clean Architecture no projeto por dois motivos:

  • Dentre as opções existentes hoje, creio que seja a menos complexa para quem está iniciando nesse mundo de arquitetura;
  • É hoje a mais utilizada em projetos mobile, portanto, se você entender os conceitos de Clean, você estará pronto para atuar na maioria dos projetos;

Mas a pergunta que pode ficar é: Na prática, o que uma arquitetura difere da outra?

Basicamente, a escolha da arquitetura é quem vai ditar a forma como seu aplicativo será estruturado. Desde quais camadas vai possuir, nome de pastas (embora esse ponto seja questionável), e obviamente, como as camadas vão se comunicar entre si, ou seja, quem vai poder "ver" quem.

The Clean Architecture by Robert C. Martin

Trazendo para nosso exemplo prático, que é o projeto BaseDroid, podemos perceber que apesar de não seguir fielmente as camadas da imagem acima, ele é separado em camadas (pastas), nomeadas como:

Imagem do projeto BaseDroid
  • Data: É a camada mais externa da imagem do Uncle Bob. É onde fica toda a comunicação com o "exterior" do nosso aplicativo, podendo ser um banco de dados, uma API, etc.
  • DI: É uma camada "apartada", que se fez necessária pois esse projeto utiliza injeção de dependências. Nesta camada realizamos toda a configuração do Koin e declaração dos módulos.
  • Domain: É a camada de regra de negócios. É onde fica os UseCases na imagem do Uncle Bob (e no nosso caso também).
  • Presentation: É a nossa camada de, literalmente, apresentação. Onde ficam nossas activities, fragments e também viewModels.
  • Existe uma pasta chamada "Utils" que conterá todos as nossas classes de utilidades (como a Interface de Mapper que já possui, como qualquer outra Extension que seja necessária criar. Eu costumo deixá-la fora das camadas acima.

O mais importante a pontuar é que as camadas precisam ser fielmente isoladas, para que, em um processo de refatoração, por exemplo, seja necessário mexer somente onde será modificado, sem impactar nas demais camadas. Por exemplo:

Digamos que no início, nosso projeto salvava todos os dados no SharedPreferences*, e que agora os dados passarão a ser armazenados em um banco de dados local (Room, por exemplo). A única camada que precisaria ser refatorada é a camada de Data, pois ela é a única (ou ao menos, deveria ser) que possui o conhecimento de onde os dados são armazenados.

*SharedPreferences é uma forma nativa do Android para armazenamento de dados, porém, somente dados simples e em pequenas quantidades. Por esse motivo só é recomendado sua utilização em casos pontuais.

Mas lembra que eu comentei lá em cima que a definição de uma arquitetura diz respeito também a como as camadas se comunicam entre si? Isso é um dos pontos fundamentais (se não o mais fundamental) de uma arquitetura bem definida. Por exemplo, a camada de domain não deve chamar a camada de presentation. Da mesma forma que a camada de data nunca deve conhecer o que há dentro da camada de domain. Ficou confuso? O desenho abaixo exemplifica:

Exemplificação das chamadas

Perceba que o usuário realizar uma ação no seu aplicativo dispara a ação em sua Activity, que por sua vez, chama a viewModel, que chama o useCase e assim por diante.

Ou seja, você não verá um Repository, por exemplo, chamar um UseCase, mas sim, algum dos Data Source. Da mesma forma que uma viewModel não deve chamar diretamente um DataSource (pulando a camada de Domain). É como diz o ditado: cada macaco no seu galho.

Você sabia que a classe Repository está na camada de Data, mas também tem um "pézinho" na camada de Domain? E que isso é essencial para manter o desacoplamento das camadas?

Quer entender como transitamos os dados de uma camada para outra, sem necessariamente, criar uma dependência entre elas? É um assunto para o próximo capítulo de "Arquitetura para iniciantes".

Se tiver curiosidade, estude um pouco mais do projeto BaseDroid e veja quais arquivos temos em cada uma das camadas apresentadas acima.

Dúvidas e/ou sugestões? Me chama no LinkedIn.

Até a próxima!

Code Like a Girl 👧

--

--

Aline Souza
Aline Souza

Desenvolvedora Android, apaixonada por tecnologia, e aprendendo todo dia um pouco mais! Code like a girl :)