Pesquisar

segunda-feira, 3 de setembro de 2018

Parte 2  -  Qual a melhor arquitetura para aplicações iOS? MVVM?

Dentre várias arquiteturas que existem e que estão por vir, existe uma que consiga resolver todos os problemas, certo?!

Na parte 1 do artigo (Qual a melhor arquitetura para aplicações iOS? MVC?) foram traçadas três características que determinam uma boa arquitetura:

  • Fácil de usar.
  • Responsabilidades distribuídas.
  • Pode ser testada.

Vimos que o MVC de acordo com sua origem funcionou e ainda funciona para outros contextos e compreendemos a diferença do MVC da Apple e suas problemáticas.

Nesse artigo, iremos analisar a arquitetura Model-View-ViewModel ou mais conhecida como MVVM.



Antes de falarmos sobre o MVVM para aplicações iOS, vale um entendimento de seu surgimento e quais foram as necessidades.

Em 2005 Jogn Gossman publicou em seu blog o artigo: Introduction to Model/View/ViewModel pattern for building WPF apps. O motivo maior de Jogn é remover completamente a parte lógica da UI, quando analisada a arquitetura em MVC e permitindo que a camada fique totalmente independente da camada view. Baseado em linguagem de marcação (XAML), torna-se muito fácil alterar os elementos de interface quando não possuem regras e aumentando a cobertura de testes.

Tanto o MVVM que Jogn da Microsoft apresentou quanto o Presentation Model em que Martin Fowler publicou em seu artigo, em que cada camada view possui uma camada abstração com algumas regras, os dois tem como objetivo simplificar e realizar a distribuição de responsabilidades. Tornando sua aplicação mais testável e fácil de usar.

Importante:

While several views can utilize the same Presentation Model, each view should require only one Presentation Model. Fonte: Martin Fowler

As views podem utilizar o mesmo Presentation Model, mas cada view só pode ter um único Presentation Model.

MVVM

Vamos analisar o MVVM apresentado por Jogn Gossman:

Fonte: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel

Model

Da mesma forma que o MVC, a camada model no MVVM refere-se a camada de dados, representa o conteúdo e pode possuir regras de negócio.

View

Assim como o MVC (em teoria quando visto o MVC da Apple) é a camada que possui toda estrutura de UI e a mais próxima do usuário.

ViewModel

É a camada intermediária entre a view e model , sendo responsável pela parte lógica da camada view e que possui acesso as informações na camada model.

MVVM em Aplicações iOS

Ao trabalharmos com MVVM no desenvolvimento de aplicações para iOS seguimos as mesmas responsabilidades das camadas apresentadas anteriormente: model, view e viewmodel, mas no caso da Apple como visto no parte 1 desse artigo, o controller e a view na prática terminam sendo uma só. Por esse motivo temos a seguinte estrutura da arquitetura MVVM:

Estrutura MVVM

O exemplo de aplicação do MVVM utiliza o serviço https://httpbin.org/headers do site httpbin.org. O código faz uma requisição e um parse das informações para apresentar na tela através do componente UITableView do framework UIKit.

Aplicando MVVM

Modelo

Como comentando anteriormente no artigo, a camada modelo refere-se aos dados e pode possuir algumas lógicas. Tomemos como exemplo um modelo que possui duas informações do tipo string.

No exemplo criado, criamos a seguinte estrutura:



Nesse artigo não irei apresentar as vantagens de utilizar struct ou class para representar os modelos. Por esse motivo, foi utilizado objeto.

Observe que a classe Info possui as propriedades title e detail que devem ser passadas no construtor. Ela também possui um método chamado description que tem como saída uma string informando o título e detalhes. Nesse caso não foi feito nenhum tratamento, mas poderia ser feito algo como substituir string vazia por alguma outra informação.

ViewModel

Na viewmodel é comum adotar a nomenclatura de VM ou ViewModel no sufixo do nome da classe, para facilitar o desenvolvimento. No nosso exemplo, criamos uma classe chamada MyViewModel que é usada em MyViewController. Seu papel é fazer o transporte das informações entre as camadas View e Model, assim como encontraremos a parte lógica da camada View.



Observe que como pattern, a ViewModel respeita seu conceito e realiza toda parte lógica para a camada View e acesso ao Model. Existem várias formas de fazermos a parte de notificação para que a view possa atualizar o que apresenta em sua interface ao usuário. O mais conhecido é usarmos o KVO.

Key-Value Observing ou KVO da Apple é utilizado para identificarmos as alterações em propriedades específicas de um outro objeto. No caso do exemplo, foi preferível simplificar para focarmos na parte conceitual do pattern. Criamos uma propriedade que é um closure e será executada toda vez que ocorrer uma alteração na lista.



Observação

A camada ViewModel no exemplo do artigo possui chamadas para a camada de serviço, pois em seu conceito do MVVM ele é tratado para resolver o problema em relação a aplicação possuir views com regras/lógicas de negócio e remover a ligação com a camada modelo. O que não impede de ser determinado que a VM (ViewModel) tenha acesso aos serviços.

View

Como dito anteriormente sobre a camada view da Apple em relação a construção de telas, pensamos imediatamente na classe UIViewController, do framework UIKit e sabemos que a UIViewController possui em sua dependência uma view. Isso foi tratado na primeira parte do artigo sobre MVC e abaixo uma representação de sua estrutura:

ViewController da Apple

No caso do MVVM, quando analisado na construção de tela, tratamos as camadas View e Controller como uma só. Ela irá possuir uma dependência da ViewModel, pois se trata de uma camada que deve fazer somente o papel de apresentação. Veja o código abaixo para entender melhor:



Observe que a classe MyViewController implementa os protocolos UItableViewDataSource, mas não possui nenhuma lógica. Essa parte a ViewModel ficou responsável. Seguindo o objetivo do MVVM, em que cada View possui um ViewModel, as células são representadas pela classe Cell:



Como toda View, a classe Cell recebe um ViewModel com a seguinte estrutura:



Essa classe tem acesso ao modelo e possui a lógica para apresentar as informações na camada View através do método labelValue.

Fazendo uma análise baseado nos critérios determinados anteriormente a respeito do que uma boa arquitetura deve ter como característica, temos os seguintes resultados:

  • Fácil de usar. ✓
  • Responsabilidades distribuídas. ✓
  • Pode ser testada. ✓

Conclusão

MVVM foi criado basicamente para diminuir a responsabilidade da camada View e tornar seu código mais testável. Tendo como objetivo, inserir um novo elemento chamado de ViewModel entre as camadas View e Model, possuindo as lógicas que antes ficavam na UI.

Referências