Design Pattern: State

Vinicius Climaco
5 min readNov 28, 2022

--

Hoje (28/11), dia do jogo do Brasil vs Suiça pela Copa do Mundo 2022 e cá estamos nós a aprender mais um Padrão de Projeto, na semana passada começamos com a família Comportamental da lista do GoF, vimos o Chain of Responsability que temos um encadeamento de responsabilidades e fizemos uma analogia a topologia de rede chamada Barramento, confira depois no artigo.

Desta vez é o Padrão State, tratamos de um padrão que visa a diminuição de condicionais como if-else ou diversos switch cases no seu código para determinar certas mudanças no estado do objeto.

Definição GoF

Permite que um objeto altere seu comportamento quado seu estado interno muda. O objeto parecerá ter mudado sua classe.

Cotidiano

Em nosso dia-a-dia temos um objeto bem usual de mudança de estado e talvez você já tenha notado isso, mas não possivelmente não tenha associado ao Padrão State… Sim, estou falando dos milhares de semáforos espalhados em sua cidade e seja você: pedestre ou motorista, deve se atentar aos semáforos. Atenção ao trânsito evita acidentes!

O funcionamento de um semáforo é bem simples, suponha que o estado atual é verde, próximo estado seria amarelo e em seguida seria vermelho. Agora pense nas diversas condicionais que você teria que inserir para validar se um estado está no vermelho, amarelo ou verde e para qual você deveria mudar o estado atual? Começou a ficar confuso…

Semáforo

O Padrão State chega justamente para facilitar sua vida e melhorar a qualidade do seu código, vamos supor que o semáforo ganhe mais uma cor e que você deve tratar isso agora no código e lá se vai mais if-else… Com Padrão State não é verdade, você teria que criar mais uma classe para tratar deste novo estado e pronto! Não acredita?! Vem comigo…

Diagrama UML

Diagrama UML do Padrão State

Acima temos o Diagrama UML representando o Padrão State, assim como outros padrões, entendo que não há tanta complexidade na adoção do State, vamos a definição de cada componente:

  • Context — temos a interface de interesse para o requisitor (Client) e mantemos no contexto a instância para subclasse do ConcreteState definindo assim o estado atual do objeto.
  • State — interface que encapsula os comportamentos associados a cada estado no contexto.
  • ConcreteStateA, B —encontramos as subclasses com a implementação do comportamento para cada estado e seus respectivos comportamentos a cada mudança de estado.

Implementação

Conforme dito anteriormente, nossa implementação de hoje estará baseada no funcionamento dos Semáforos, pois o mesmo tem um controle de estado e existe uma regra de negócio associada aos estados, onde deve seguir uma sequência.

Para darmos início a prática, abaixo segue o Diagrama de Classes com os respectivos componentes: Context, State e ConcreteState.

Diagrama de Classes do padrão State.

Na sequência temos a interface representando o componente State, podemos observar que neste estão definidos quais estados teremos em nosso contexto.

State representado por ICores

As classes ConcreteState estão representando como cada estado deve funcionar e até mesmo se a sequência estaria correta, por exemplo: Amarelo mudando seu estado direto para o Verde, imagina o caos no trânsito da cidade e até mesmo risco de acidentes?!

ConcreteState representado por Amarelo
ConcreteState representado por Verde
ConcreteState representado por Vermelho

Para finalizar os componentes mínimos a fim de compor nosso Padrão State, seguimos com o Context que armazena o estado atual.

Context representado por Semaforo

Concluindo com a implementação de um requisitor (Client), na qual temos as instruções de nosso projeto para troca dos estados e instruções ao usuário final.

Client sendo representado pela Program.cs
Resultado final do nosso projeto.

Observe que acabamos de criar uma espécie de ‘jogo’, na qual o objetivo é identificar o próximo estado que o semáforo deveria adotar. Conforme pode ser visto este é um cenário mais didático, porém tenta inserir mais um estado em seu semáforo e veja como tudo fará sentido, agora pense num sistema varejista na qual controla o estado atual da venda de mercadoria em sites de e-commerce por exemplo, você teria que orquestrar de qual status irá para qual sem pular etapas para não haver qualquer tipo de erro. Entendeu a importância do uso do Padrão State?

Prós e Contras

Como algo positivo e já foi dito neste artigo: reforço a diminuição de declarações com if-else ou similares, ou seja, seu código mais limpo. Temos uma outra vantagem que é a utilização do princípio Open/Close, na qual você poderá adicionar novos estados e estender o comportamento de forma facilitada.

Negativo cito a adição classes em nosso código, aumentando a complexidade de manutenção, porém é um efeito colateral que devemos tolerar, pois os ganhos na minha visão é muito superior.

Código Fonte

Baixe o código fonte no GitHub através deste link — ajuste, altere, inove através do Padrão State, evolua com o exemplo apresentado e comente abaixo sobre suas mudanças.

Por hoje é só pessoal…

Agradecendo a todos que me acompanham na série de artigos que venho fazendo há alguns meses sobre Padrões de Projeto e semana que vem (05/12) tem mais… estaremos com o Padrão Strategy. Vem comigo!!!

Forte abraço e até a próxima…

--

--

Vinicius Climaco

Tech Speaker | Solutions Architect | Microsoft MVP | Aws Community Builder