Concrete Logo
Hamburger button

Como usar o State Design Pattern para criar um Stateful ViewController

  • Blog
  • 7 de Setembro de 2018

O que diabos é um ViewController Stateful? Um ViewController Stateful é o nome dado por nós para um ViewController que tem muitos estados e deve ser capaz de alterar suas views ou componentes com base em seu estado atual.

Criar um pode ser complicado, primeiro podemos ter diferentes telas de loadings e/ou telas de erro. Por exemplo, em nosso LoginViewController temos um loading dentro do nosso UIButton e as mensagens de erro devem ser tratadas com um alerta personalizado. Nosso HomeViewController deve mostrar uma tela de loading e uma de erro padrão que sabe como tratar com um Error.

Queremos construí-lo de uma forma que não precisemos repetir códigos ou comportamentos em muitos view controllers.

Podemos usar um State Design Pattern para lidar com isso. O State Pattern é por definição:

Um padrão de design de software comportamental que permite que um objeto altere seu comportamento quando seu estado interno é alterado. O State Pattern pode ser interpretado como um padrão de Strategy capaz de alternar a estratégia atual, por meio de invocações de métodos definidos na interface.

Definindo o nosso estado

Definimos alguns estados como .success, .loading e .error (error) e achamos que ia ser ótimo criar um protocolo e adicioná-lo ao nosso ViewController.

O problema dessa abordagem é que todo o view controller vai ter um switch case gigante e provavelmente um código repetido.

– “Sim! Sim, mas pode resolver essa criação funcs”.

– Ok! Mas isso não vai resolver nosso problema, apenas vai disfarçá-lo.

Um outro problema é: “o que acontece se adicionarmos outro estado?”

Sim! Precisamos adicioná-lo a cada switch ou criar um default. Adicionar outro estado vai fazer com que tenhamos que modificar todas as classes que usam nosso protocolo Statable quebrando o princípio de aberto-fechado.

Criando um protocolo de estado único

Pensamos que seria melhor se nós mudássemos nosso ‘enum’ e ‘protocol’ para um novo ‘protocol’:

Muito melhor agora! Isso eliminou o problema do ‘switch case’, mas não era exatamente o que queríamos.

E agora todos os view controllers precisam ter esses três métodos, mesmo que tenham uma tela de loading ou erro padrão. Em outras palavras, ainda estamos repetindo o código.

Costumo dizer que:

Se você tiver um método de protocolo que tenha uma implementação default, ou que não seja usado em todas as classes/structs, esse método não deveria estar lá.

Quebrando o nosso protocolo

Alguns view controllers não precisam implementar ‘setLoadingState ()’ ou ‘setErrorState (error: Error)’, isso vai ser tratado por classes padrões. Então decidimos dividir o nosso protocolo em três.

Isso vai ser ótimo, porque podemos criar visualizações de padrão de erros e de carregamento:

Default loading view

Default error view

Manipulando Default States

Finalmente, podemos criar um Decorator no nosso ViewController para lidar com todos os estados e alternar entre eles sempre que precisarmos.

Conclusão

Com essa abordagem, podemos ter exibições de erros e loading personalizados quando precisarmos e implementações padrões quando uma personalizada não é necessária. Podemos criar muitas classes diferentes para lidar com loadings, tornando nosso DefaultLoadingState fechado para modificação e aberto para extensões.

Nós misturamos o State Design Pattern e o Decorator Pattern para criar um StatableViewController que vai ser responsável por manipular os estados do nosso view. Usando a injeção de dependência, podemos alterar os comportamentos de loading e o erro de nossos controllers em um único ponto de entrada.

PS: Se você gostou deste post, compartilhe no Twitter, recomende ele, ou ambos =). Isso realmente me ajuda a alcançar mais pessoas. Muito obrigado.

A Concrete é uma empresa da Accenture especializada no desenvolvimento ágil de produtos digitais. No capítulo de iOS temos a oportunidade de viver em uma comunidade prática com dezenas de desenvolvedores iOS, trocando conhecimento e compartilhando informações técnicas e práticas. Além de desafiadores, os projetos têm acompanhamento próximo dos gerentes, que estão sempre buscando entender o momento de cada membro do capítulo, considerando seus próximos desafios e oportunidades de crescimento e visando a melhoria contínua e evolução de todos. Práticas ágeis, lean, visão de produto e engenharia sólida são pilares que serão incorporados desde o primeiro dia até se tornarem quase que uma segunda natureza. Quer fazer parte disso? Acesse: concrete.com.br/vagas