Os conceitos e princípios da modularização para aplicação Mobile
Nesses quase 7 anos como desenvolvedor mobile, encontrei poucos artigos que abordassem os conceitos e princípios da modularização no contexto mobile. Isso me motivou a criar este artigo, com o intuito de compartilhar meu aprendizado com os leitores. Espero que você goste e tenha uma boa leitura.
A modularização tem o princípio de dividir aplicação em módulos independentes e coesos e que cada um execute uma função específica.
O objetivo é:
Dependendo no tamanho da equipe, produto e time na empresa, podemos seguir o projeto em duas estruturas, mono-repo, ou seja, os módulos ficam no mesmo repositório ou multi-repo, que seria o módulo com seu próprio repositório e que seria publicado em algum gerenciador de biblioteca - Maven para o Android, CocoaPods e/ou SPM (Swift Package Manager) para o iOS e Flutter Package (Pub.dev) para o Flutter.
Abaixo há um diagrama que elucida este conceito, pensando na aplicação mobile:
Nesse diagrama temos 6 módulos: Security, Core, Feature, Analytics, DesignSystem e Service. Nos próximo paragráfos irei explicar o conceito e objetivo de cada módulo.
Módulo de Security:
Este módulo tem o objetivo de buscar variáveis de ambiente em algum serviço remoto (usamos muito o RemoteConfig do Firebase, mas poderia ser feito através de uma API) e armazenamos essas variáveis de ambiente em um armazenamento criptografado (no mercado temos EncryptedSharedPreferences para o Android e o KeyChainStorage para o iOS), além disso tudo que tem a principalidade de segurança podemos adicionar nesse módulo. Esse módulo é recomendável deixá-lo separado em um repositório independente.
Módulo de Core:
O módulo Core centraliza todas as funcionalidades básicas necessárias para os módulos de funcionalidades (feature module), ou seja, BaseView, BaseViewModel, BaseUtils e entre outros bases. Tendo o objetivo de adicionar funcionalidades que impactem todos os módulos que dele herdam.
Recomendados pelo LinkedIn
Módulo de Features:
Esse módulo é uma representatividade de como as funcionalidade do produto devem ser criadas, ou seja, cada produto tem seu módulo separado dos demais.
Pense no Instagram, o Instagram tem a área de acesso (login), a funcionalidade de Feed, o Perfil e entre outras funcionalidades. Cada funcionalidade está separada por módulos que podem se comunicar ou não entre eles mesmos - a comunicação vai depender se faz sentido.
Nos projetos que trabalhei criamos uma camada Router na aplicação principal e caso a funcionalidade X precise chamar a funcionalidade Y, faz través de uma interface que o módulo Core tem, ou seja, aplicação X passa os parâmetros que a interface do Core precisa para chamar aplicação Y (nem sempre precisa passar os dados), o Core está conectado com aplicação principal e solicita essa chamada, removendo a responsabilidade das funcionalidades de chamar umas a outras.
Nesse módulo separei em três camadas, a de visualização, regra de negócio e o de dados. Cada projeto tem sua arquitetura de funcionalidades que pode ser: MVP, MVI, VIPER, Bloc e a mais utilizada a MVVM, as diferenças entre cada arquitetura e como é feita suas conexões entre elas e quais recursos são utilizados (Rx, Await, Coroutines, LiveData e entre outros). O importante é separar as camadas corretamente para conseguir testá-las.
Módulo de Analytics:
O objetivo deste módulo é centralizar as bibliotecas de metrificação (firebase, amplitude, mixpanel e entre outros) em uma única fonte, ou seja, criar uma classe (Proxy + Adapter) que chame todas essas bibliotecas e colocar um padrão de como o cliente (os módulos que chamarem) pode passar os dados.
Módulo de DesignSystem:
Acredito que seja um dos módulos principais para a escalabilidade na aplicação mobile e na maioria das vezes é o primeiro módulo a ser criado, pois vai ser o módulo mais utilizado na aplicação em geral, ou seja, todos componentes de visualização (botões, lista, widget e entre outros) e os tokens (cores, espaçamento, fontes, imagens, ícones, animações e entre outros) vão ser criado a partir dele.
Em regra, esse módulo consiste em input e output, ou seja, o cliente passa os dados ou comportamento que ele quer e o componente retorna o desejado.
Módulo de Service:
Por fim, o módulo de comunicação com a RestAPI ou outra fonte de serviço ex: Firebase Storage. Este módulo centraliza os caminhos das API, as criações nos serviços e as estruturas de dados (entities ou data) nas requisições e respostas. Essa camanda também tem a responsabilidade por tratar dos erros que o serviço retornar e com ajuda no módulo de Analytics metrificar o sucessos e erros no serviço. A parte nas chaves de criptografia, descriptografia e base URL, o módulo de Security o fornece.
Em resumo, a modularização venho para simplificar o modo de como estruturamos as nossas aplicações mobile, facilitando na manutenção, na intercambialidade e o aumento na produtividade e qualidade do produto.