Menu

Escrevendo aplicativos móveis de qualidade em qualquer arquitetura

No início, havia o MVC (Model-View-Controller) — por um longo tempo o padrão principal promovido por Apple e Google em seus tutoriais de desenvolvimento iOS e Android. O MVC foi um bom ponto de partida para pessoas desenvolvedoras de dispositivos móveis, mas ele veio com um custo: uma fixação nos padrões de arquitetura. Hoje, quero incentivar você a adotar uma nova maneira de pensar; aquele que oferece os benefícios dos padrões de arquitetura sem inchar o código.
Com a chegada do MVC, a comunidade avançou rapidamente. O MVP (Model-View-Presenter) apareceu, tentando corrigir o problema do
"tudo dentro do meu controlador" pcom o MVC. Ao mesmo tempo, o MVVM (Model-View-ViewModel) adicionou o View Model para representar sua visualização e o estado.

Essa sopa de novas idéias e arquiteturas explodiu: VIPER, MVC, MVI, VIP, ReSwift, só para citar alguns. Cada um propondo maneiras diferentes de arquitetar seu aplicativo.

Figura 1: sopa de letras
Figura 1: sopa de letras

Ao mesmo tempo, as discussões na comunidade móvel tornaram-se mais acaloradas: o MVC está errado? O MVVM leva a enormes e inatingíveis ViewModels? O VIPER é uma solução complexa e exagerada? Qual é a melhor escolha?

Nenhuma dessas discussões é inválida, mas as pessoas tendem a esquecer alguns pontos cruciais:
  • Todas essas siglas são padrões arquitetônicos. Seu aplicativo não está no MVP nem no VIPER; seu aplicativo usa MVP ou VIPER - essa é uma diferença realmente importante que exploraremos mais adiante no artigo.
  • Seu design de arquitetura pode seguir qualquer um desses padrões e ainda ter um código não testável, ilegível e confuso.

Precisamos de mais do que uma sopa de letras

Há uma piada antiga que captura bem alguns dos problemas com o MVC: "MVC deveria significar Massive View Controller". E quando se trata de visualizar o controlador ou a atividade, o massivo torna-se um problema: confuso, complicado, ilegível e não-testável.

Mas tudo isso vale apenas para MVC? Acho que não.

Se você acessar seu banco de dados diretamente de sua atividade, isso não é culpa do MVC. Você está fazendo chamadas de rede do seu controlador de visualização? Isso também não é culpa do MVC. Você precisa gerenciar estados em seu fragmento? Adivinha? MVC não é o único culpado.

MVC significa que sua base de código será estruturada em torno de modelos, visualizações e controladores. Isso não significa que tudo deve caber em uma dessas três caixas.

Vamos tomar VIPER como outro exemplo. Nesse caso, a sigla nos diz que devemos ter um View, Interactor, Presenter, Entity e (ufa!) Router. Mas você provavelmente também precisará de uma camada de acesso ao banco de dados, uma camada de rede, GPS, persistência de disco e assim por diante.

Assim como o MVC, o VIPER é um padrão de arquitetura que sugere entidades em torno das quais você deve arquitetar seu aplicativo. Novamente: isso não significa que você deva encaixar tudo dentro das cartas propostas. Você tem liberdade. Pode criar quantas camadas você precisar para manter seu design consistente.

Você pode ter resultados catastróficos com o MVC? Sim. Assim como você pode ter os mesmos problemas com o VIPER ou o MVVM.

O padrão arquitetural se adapta ao seu aplicativo. Não o contrário. Esses padrões funcionam como "sugestões" para sua arquitetura — e não como receitas em que você usa os mesmos ingredientes seguindo as mesmas etapas para obter os mesmos resultados.

Seu aplicativo precisará de mais que três ou cinco letras se você quiser manter uma arquitetura saudável, sustentável e organizada.

Aproveitando os padrões

O maior benefício dos padrões é que eles propõem uma comunalidade. O MVVM, o MVP e todos os outros foram obtidos por reutilização, observação e refinamento contínuos, resultando em uma abstração.

Padrões são uma ajuda, um guia, uma direção. Eles não são a solução. Eles não são uma religião. Eles permitem, por exemplo, uma integração mais rápida para uma nova pessoa na equipe, porque a pessoa pode ter experiência anterior com esse padrão de arquitetura.

Mas eles não garantem testes, código limpo, boas práticas de desenvolvimento e nenhum deles irá salvar você de ter bugs recorrentes ou um software não-resiliente. Boas pessoas desenvolvedoras e boas práticas, sim.

O que nos leva ao próximo tópico.

Uma nova maneira de pensar

Eu gostaria de propor um novo padrão para projetos móveis. Mais do que isso: pilares com os quais sua equipe precisa concordar. Pilares para guiar. Uma nova mentalidade. Um pacto, chamado PACTS:
Figura 2: Padrão (aqui você pode usar o que faz sentido para suas necessidades: MVC, MVP, MVVM, VIPER…) + Código limpo + TDD & testes + SOLID

Princípios representados por um acrônimo de padrão, código limpo, testes/TDD e SOLID.

Ele consiste em:
  • Padrão: MVC, MVP, MVVM, VIPER ou qualquer outro. Não o siga cegamente: ajuste o padrão em seu design, e não o contrário.
  • Código limpo: escrever código que funciona é fácil. Escrever um código simples, focado e elegante que é feito para os humanos entenderem, não é tanto. Escreva um código que você entenderá no futuro.
  • TDD & testes: se o seu código é limpo e organizado, mas não tem testes, você invariavelmente sofre com a falta de resiliência, vários erros e um longo MTTR (tempo médio de reparo). Um código bem testado é um bom código.
  • SOLID: sua arquitetura precisa ser compreensível, flexível e sustentável. Um código limpo e testado que não pode ser desenvolvido causará problemas.
Se você e sua equipe aplicam os três últimos tópicos (a parte "CTS"), as chances de um bom código, com uma arquitetura sustentável e fácil de evoluir, são maiores— independentemente do padrão adotado.

E, sobre o padrão, qual seria o melhor? Somente sua empresa, equipe e contexto podem responder a essa pergunta. O VIPER pode ser um exagero em um aplicativo simples com uma equipe de duas ou três pessoas desenvolvedoras. Mas isso pode trazer benefícios em um aplicativo maior com equipes de dez ou mais pessoas.

Talvez o MVC caia como uma luva para você. Isso mesmo, MVC.

Ou, talvez, nenhum desses padrões resolva seu problema. Neste caso, você pode criar o seu próprio. Pode até ser uma mistura do que já existe: nada impede que você use modelos de visualização em conjunto com o VIPER, por exemplo.

Projetar, testar, refatorar e reiniciar o processo.

Quem sabe se sua próxima arquitetura chegará ao hall da fama? Nesse caso, lembre-se de que você não está criando um time de futebol: é apenas um padrão que não deve ser seguido de forma servil.

Precisamos de boas pessoas desenvolvedores, bom código e testes bem escritos. Chegou a hora de fazer esse pacto.