Por que utilizamos VIPER?

Bruno
Involves Rocks
Published in
5 min readFeb 14, 2018

Já faz algum tempo que muitos desenvolvedores - mais voltados para a comunidade Apple, com a qual eu tenho mais contato - têm discutido sobre arquiteturas recomendadas para seus projetos. E os questionamentos que destaco são:

  • Qual é a melhor arquitetura ?
  • O que a comunidade tem usado mais?
  • Quais são as melhores práticas para tal arquitetura ?
  • E é claro, como evitar esta figura:

Difícil de reaproveitar código, arquivos gigantes, difícil de seguir o SOLID, etc. Estas, sem dúvida, não foram as reais razões pelas quais me motivei a escrever este post, mas sim pelo fato de ter lido a seguinte frase, no slack do iOSDevBr:

"Implementando pela primeira vez o VIPER, chego a seguinte conclusão: CRIARAM UM MONSTRO."

VIPER, para quem não sabe, é uma abordagem para desenvolvimento de aplicação com base na arquitetura limpa (a Clean Architecture) especialmente para o iOS. A Clean Architecture, de forma bem resumida, divide nosso software em camadas. Seu objetivo é separar a estrutura de lógica da aplicação em diversos caminhos de responsabilidade.

VIPER

Em março de 2017, quando entrei para a Involves 🎉, tive o meu primeiro contato com o VIPER. Antes disso, eu já havia trabalhado com o famoso MVC da Apple (😱) e claro, MVVM.

MVC
MVVM

Durante o processo de contratação da Involves, os devs iOS (Pietro Caselani e Felipe Lobo) mencionaram que estavam trabalhando com VIPER já faziam alguns meses. Ninguém percebeu, mas quase dei um pulo da cadeira de tamanha felicidade, pois finalmente eu teria a oportunidade de trabalhar com uma arquitetura que sempre tive muito interesse, mas que nunca tive oportunidade de aplicar no mundo real.

Durante a entrevista eu fiquei 🤔 sobre VIPER, e algumas dúvidas vieram a minha cabeça:

  • Como será que deve estar toda a arquitetura do projeto no qual eles estão trabalhando?
  • Será que estão seguindo os passos do Clean Architecture.

Estas curiosidades não demoraram muito para serem desvendadas. Alguns dias se passaram, finalmente fui contratado pela Involves e então, tive a oportunidade de poder ver como o projeto do Agile Promoter estava funcionando no iOS.

Meu primeiro questionamento aos devs foi: "Por que utilizamos VIPER ?". Apesar de estar ciente sobre com o que eu iria trabalhar, fiquei muito curioso quanto a necessidade de aplicar ele no projeto atual e claro, o PC (aka Pietro Caselani), me respondeu:

Nós usamos VIPER porque ele deixa todo o código desacoplado, as responsabilidades de cada camada são mais claras e objetivas. Podemos fazer os testes unitários com mais facilidade e quando nós precisarmos migrar um banco de dados para outro, o impacto será muito menor.

Em seguida, o Lobo (aka Felipe Lobo) me respondeu:

Nós temos um domínio muito maior em cada camada da aplicação (View, Interactor, Presenter, Entity, Router), assim evitando o famoso Massive View Controller, que é exatamente o que nós não queremos aqui, certo? Mas fica tranquilo, não somos 100% fiéis ao Clean Archicteture. Nós estamos moldando o que o VIPER oferece ao nosso estilo de programação aqui na Involves.

Achei muito bacana os motivos pelo qual eles estavam utilizando VIPER na aplicação e, principalmente, pela última frase que o Lobo comentou: “estamos moldando ao nosso estilo de código”.

Apresento um caso que nós temos hoje no Agile Promoter iOS. É o Conteúdo Dinâmico. Sim, algumas modificações foram feitas no código para facilitar entendimento ao leitor.

  • Primeiramente, vamos criar nossa classe com todos os Contratos/Protocolos. Qualquer classe que herdar de qualquer Protocol, deverá respeitar sua assinatura.
  • Após criar nossos Contratos/Protocolos, iremos fazer o mesmo para o Módulo. Quem for chamar o módulo, precisará informar ao init qual é o Point Of Sale no seu parâmetro e, no corpo do init, inicializamos nossa View, Presenter, Interactor. Como nós herdamos o Router, ele não precisa ser inicializado.
  • Assim que nós inicializarmos o Módulo, criaremos o Presenter, responsável por solicitar o Interactor aos dados do conteúdo dinâmico e avisar a View que já temos os dados para serem apresentados na tela do usuário.
  • Após injetar as dependências no Presenter, vamos criar o Interactor. Nosso interactor tem o papel de command Pattern. Basicamente, é um padrão no qual um objeto é usado para encapsular toda a informação necessária para executar uma ação.
  • E, finalmente, chegamos ao nosso View. Ele possui a função de apenas apresentar as informações na tela e acionar o Presenter por meio do disparo do evento no toque na tela. No nosso caso, o disparo ocorre quando o usuário seleciona um conteúdo na tela e é redirecionado para uma outra tela. O responsável por fazer está transação é o Router, que é chamado pelo Presenter.

Finalmente temos nosso conteúdo dinâmico funcionando. Podemos ver toda a separação das responsabilidades das camadas com uma pitada do nosso estilo de usar o VIPER e assim, evitar o famoso Massive ViewController. E claro, não criamos nenhum MONSTRO.

Uma curiosidade: podemos adicionar Rx no código que apresentei e, o mais legal é saber que a aplicação sofrerá pequenas modificações devido as camadas que o conteúdo dinâmico possui :)

Então…

No começo parece ser complicado de entender como tudo está orquestrado, mas depois que você começa a montar as partes (tipo LEGO), tudo vai se encaixando e fazendo sentido. O poder da reutilização de código em outros projetos é mais fácil, por exemplo, criar um módulo para o AppleWatch. Testar ficou mais fácil. O prazer de remodelar qualquer tela da aplicação sem ter que se preocupar com a regra de negócio, pois está bem isolada. Não ter que fazer busca no banco de dados dentro do ViewController ou em Models é uma alegria indiscutível.

--

--