Android MVC x MVP x MVVM qual Pattern utilizar — Parte 1
Este artigo será divido em 2 partes. Inicialmente, iremos falar dos Patterns de arquitetura já utilizados, sendo eles :
- MVC - Model View Controller
- MVP - Model View Presenter
- MVVM - Model View ViewModel
Na primeira parte, farei uma comparação entre MVP e MVVM. Trarei os conceitos, uma comparação entre eles, como funciona cada um deles, e por que ocorreu a evolução de novos Patterns.
Tentarei passar da forma mais clara possível, para que com isto vocês tenham um ganho muito grande em seus códigos.
Na segunda parte, focarei em MVP vs MVVM e em algumas ferramentas muito utilizadas na implementação deste padrão de arquitetura, assim como utilizar conceito de SOLID.
Também falarei do porquê que foi tão falado no MVVM na Google IO este ano.
Pois bem, sem mais delongas, vamos começar.
A galera do Android não fica parada. Sempre ligada às novas versões, novas práticas e ao constante surgimento de novas ferramentas, visando encontrar uma mítica “pedra filosofal” ou, assim dizendo, uma arquitetura ideal.
Sendo flexível para mudanças de lógica e design e, claro, sem esquecer o nosso maior amor: “ser confortável para teste”. Ser independente de estruturas externas e simples. Ok, agora você se pergunta, isto é possível? Bem, vamos descobrir.
Nos estágios iniciais, quando a plataforma Android estava apenas iniciando e havia poucas bibliotecas disponíveis, a maioria das aplicações eram escritas com padrão primitivo. Parecido com isso:
Em suma, tudo parecia ótimo, embora tivesse inúmeras desvantagens:
- Dissipação de lógica de negócios entre camada de dados e View Layer, causando duplicação de código e redução de reutilização;
- Mesclagem de classe excessiva;
- Difícil manutenibilidade;
- Impossibilidade de testar a lógica de negócios;
- Impossibilidade de troca rápida de banco de dados, mudança REST-client, dentre outros;
Com isto percebeu-se que era necessário abordar melhores práticas e novos padrões arquitetônicos para seus sistemas. Não é algo estranho, mas ao longo dos últimos anos organizar sua aplicação e componentes lógicos evolui, e com isto a comunidade deixou de lado o padrão monolito que utilizava Model View Controller, substituindo por padrões mais modestos e testáveis. Assim surgiram o Model View Presenter (MVP) e o Model View ViewModel (MVVM), duas das alternativas mais adotadas para o desenvolvimento Android.
Antes de entrar em padrões de arquitetura, falarei brevemente de ferramentas disponíveis para desenvolvedores Android. Na parte 2, me aprofundarei mais nelas, assim como ensinarei a utilizá-las. Essas ferramentas facilitam nossas vidas e nos permitem executar com maior facilidade a arquitetura que desejarmos. Seguem alguns exemplos:
- Android DataBinding - Permite a transferência de determinada lógica de aplicação em XML;
- Butter Knife - Ideia muito parecida com DataBinding, mas é uma lib externa na qual deve ser instanciada para cada View e trabalha com Annotations;
- Dagger 2 - Implementa a técnica de “Injeção de Dependência”;
- Android Annotations - Biblioteca que faz a implementação de componentes Android tão simples quanto possível, sem diminuir os recursos;
- RxAndroid - Abordagem de codificação altamente funcional, programação altamente reativa. Otimiza muitas tarefas;
- Firebase - Plataforma de aplicação móvel e web que ajuda a desenvolver aplicativos de alta qualidade;
E a lista continua, Picasso, Retrofit… No entanto, não é sobre isto que quero enfatizar.
Iniciaremos com o Pattern mais conhecid0, o MVC:
MVC
Esta abordagem separa sua aplicação em um nível macro com 3 conjuntos de responsabilidades. Sendo eles:
Model
No Model irá conter Data + State + Business Logic, de forma não técnica. Podemos usar como exemplo lógica comercial, acesso a dados e regra de negócios, que não está ligado a View ou Controller e com isto se torna muito reutilizável.
View
Representa o Model, ela é a UI (user interface) e faz a comunicação com a Controller sempre que ocorre uma interação do usuário. O ideal é que sejam “burras”, isto é, quanto menos eles souberem do que deve ser feito com a interação, mais flexíveis serão para mudar.
Controller
Ele é o responsável pelo que acontece no aplicativo. Quando a View diz para o Controller que um usuário clicou em um botão, ele decide como interagir. Se ocorrer modificação de dados no Model, o Controller pode decidir atualizar o estado de exibição, quase sempre representado por uma activity ou fragment. Há quem diga que ele é o coordenador entre a View e o Model.
Vamos ver como fica o Controller:
MVC faz um excelente trabalho de separar o Model e a View. Assim o Model pode ser facilmente testado, porque não está vinculado a nada e a View não tem muito para testar em um nível de teste unitário. No entanto, o Controller definha.
Preocupações/Problemas do Controller
- Testabilidade - O controlador está tão ligado às APIs do Android que é difícil testar a unidade.
- Modularidade e flexibilidade - Os Controllers estão bem acoplados às Views. Pode também ser uma extensão da View.
- Se mudarmos a View, devemos voltar e mudar o Controller.
- Manutenção - Ao longo do tempo, particularmente em aplicações com modelos anêmicos, cada vez mais o código começa a ser transferido para os Controllers, tornando-os cheios, complexos e com grande facilidade de crashs.
Beleza. Então, quem poderá nos ajudar? Não, não é o Chapolin colorado, mas em meados de 2015 surgiu com popularidade entre os devs android um par específico de padrões layer/design: MVP e MVVM. Eles sim irão nos ajudar.
MVP
O MVP quebra o Controller de modo que o acoplamento de View/Activity pode ocorrer sem amarrá-lo ao restante das responsabilidades do “Controller”. Veremos mais sobre isso abaixo, mas comecemos novamente com uma definição comum de responsabilidades, em comparação com o MVC.
Model
Igual ao MVC / Nenhuma mudança
View
A única alteração aqui é que a Activity/Fragment agora é considerada parte da View. A boa prática é ter uma Activity implementando uma interface de exibição para que o Presenter tenha uma interface para codificar. Com isto é eliminado o acoplamento e permite testes unitários.
Presenter
Este é essencialmente o Controller do MVC, exceto por ele não estar vinculado ao View, apenas a uma interface, com isto ele não mais gerencia o tráfego de solicitações recebidas, como é feito no Controller. Assim aborda as preocupações de testabilidade, modularidade e flexibilidade que apresentam com o MVC.
Na verdade, os puristas do MVP argumentam que o Presenter nunca deve ter referência a qualquer API ou código Android.
Se olharmos com mais clareza o código acima, percebemos que no Presenter mais simples e clara é a ação. Ao invés de dizer a View como exibir algo, ele apenas delega o que exibir. Assim podemos testar com facilidade a lógica do Presenter, pois não está acoplada a View ou API específica do Android.
Trabalhando desta forma com a View, decidindo apenas se é necessário que ela implemente a interface, existe uma relação um-para-um entre a View e o Presenter. Veja o exemplo da interface.
A View tem como referência o Presenter, mas sem referência ao Model. No entanto, nem tudo é um mar de rosas.
Preocupações/Problemas do Presenter
- Manutenção - Os Presenters, assim como os Controllers, são propensos a colecionar lógica comercial adicional, espalhados com o tempo.
- Eventualmente, os desenvolvedores deparam-se com grandes Presenters difíceis de separar.
Aí você se fala, “Ah, mas eu sou um dev cuidadoso e irei evitar isto”. Ok, acredito em você. No entanto, MVVM pode ajudar a resolver isso e fazendo menos para começar.
MVVM
MVVM com o Data Binding tem como benefícios testes mais fáceis e modularidade, ao mesmo tempo que reduz a quantidade de código que temos que escrever para conectar o Model com a View. Este Pattern suporta ligação bidirecional entre View e ViewModel, com isto nos permite ter propagação automática de mudanças. Bem, vou explicar.
Model
Igual ao MVC e MVP / Nenhuma mudança
View
A View liga-se a variáveis Observable e ações expostas pelo ViewModel de forma flexível.
ViewModel
O ViewModel é responsável por expor métodos, comandos e propriedades que mantém o estado da View, assim como manipular a Model com resultados de ações da View e preparar dados Observable necessários para a exibição.
Ele também fornece ganchos para que a View passe eventos para o Model. No entanto o ViewModel não está vinculado à View. Existe uma relação de muitos-para-um entre a View e ViewModel, o que significa que uma ViewModel pode mapear muitas Views.
Ok, descanse um pouco. Depois de ler tanto View e ViewModel, vamos dar uma olhada neste código para entendermos melhor, começando com o ViewModel… kkk Desculpe
Agora a View, para ver como essas variáveis e ações estão vinculadas.
Com isto, os nossos testes unitários se tornam ainda mais fáceis, porque você realmente não tem dependência na View. Ao testar, você só precisa verificar se as variáveis Observable são definidas adequadamente quando o Model muda. Não há necessidade de minimizar a exibição para testar como no padrão MVP.
Preocupações do MVVM
- Manutenção - As Views podem se ligar (bind) a ambas as variáveis e expressões, adicionando código efetivamente ao nosso XML. Para evitar isso, sempre obtenha valores diretamente do ViewModel em vez de tentar calcular utilizando Lambda no XML, como no último exemplo para trabalhar com VISIBLE ou GONE.
Conclusões
Acredito que todos agora veem que tanto o MVP quanto o MVVM fazem um trabalho melhor do que o MVC ao dividir seu aplicativo em componentes modulares e de propósito único, pois também adiciona mais complexidade ao seu aplicativo. Para isto é sempre bom ter no mínimo um dev com mais conhecimento (Pleno/Sênior).
Para uma aplicação muito simples com apenas uma ou duas telas, o MVC pode funcionar bem.
Agora você deve estar se perguntando: "Quando usar MVP e quando usar MVVM?". Nos casos em que a vinculação com o DataContext não é possível, a maioria dos desenvolvedores prefere MVP (o Windows Forms é um ótimo exemplo). Usa-se 0 MVVM de preferência nos casos em que a ligação com DataContext é possível, com esta ligação de dados atraente, segue um modelo de programação mais reativo e produz menos códigos. Grande solução para lidar com tarefas relacionadas ao Windows Presentation Foundation (WPF) e ao framework de aplicativos Silverlight.
Então, qual padrão é melhor para você? Se você estiver escolhendo entre MVP e MVVM, muita da decisão se resume a preferências pessoais, mas vê-las em ação o ajudará a entender os benefícios e as compensações.
Pois bem, pessoal, até a parte 2.