Artigos Rem soft Sistemas

Design Pattern State

Entendendo o Padrão State

 

O padrão State é um dos 23 padrões de design descritos no clássico livro “Design Patterns: Elements of Reusable Object-Oriented Software”, escrito por Erich Gamma, Richard Helm, Ralph Johnson e John Vlissides, também conhecido como “Gang of Four” (GoF). Este padrão visa permitir que um objeto altere seu comportamento quando seu estado interno muda. Isso é alcançado através da separação dos estados em classes separadas e permitindo que o objeto delegue o comportamento correspondente ao seu estado atual.
A essência fundamental do padrão State reside na concepção de que um programa pode existir em um número finito de estados distintos. Dentro de cada estado específico, o comportamento do programa é definido de forma distinta, e a transição de um estado para outro pode ocorrer instantaneamente. Contudo, tais transições são governadas por regras predeterminadas e finitas, conhecidas como transições. Dependendo do estado atual do programa, algumas transições podem ser permitidas, enquanto outras podem ser proibidas. Este conceito de transição entre estados define a lógica do comportamento dinâmico do programa, permitindo uma adaptação flexível às diferentes condições e requisitos em tempo de execução.

 

Uso de condicionais

Comumente, as máquinas de estado são construídas com várias instruções condicionais (como if ou switch) que determinam o comportamento apropriado com base no estado atual do objeto. Na prática, esse estado é geralmente representado por um conjunto de valores dos campos ou propriedades do objeto. Mesmo sem estar familiarizado com o termo “máquinas de estado finito”, é provável que você já tenha implementado um sistema que funcione dessa maneira em algum momento.

Mas qual o problema de usá-las?

A maior fraqueza de uma máquina de estado baseada em condicionais se torna evidente quando o sistema evolui e mais estados e comportamentos dependentes do estado são adicionados à classe do documento. Com o aumento da complexidade, os métodos tornam-se repletos de condicionais extensos que selecionam o comportamento apropriado com base no estado atual. Esse tipo de código se torna difícil de manter, pois qualquer modificação na lógica de transição requer alterações em todos os condicionais de estado em diversos métodos.

 

À medida que o projeto progride, o problema se agrava. É desafiador prever todos os estados e transições possíveis durante a fase de design inicial. Portanto, uma máquina de estado que inicialmente era concisa e organizada, construída com um conjunto limitado de condicionais, pode se transformar em uma estrutura inchada e confusa ao longo do tempo.

 

O uso do State

O padrão State propõe a criação de novas classes para cada estado possível de um objeto, onde cada classe encapsula os comportamentos específicos desse estado. Em vez de implementar diretamente todos os comportamentos no objeto original, conhecido como contexto, este armazena uma referência a um dos objetos de estado que representa o estado atual e delega todas as operações relacionadas ao estado a esse objeto.

 

Para transicionar o contexto para outro estado, substituímos o objeto de estado ativo por um novo objeto que represente o estado desejado. Isso só é viável se todas as classes de estado seguirem a mesma interface, e o contexto interagir com esses objetos apenas por meio dessa interface padronizada. Essa abordagem promove uma estrutura mais modular e flexível, onde cada estado é tratado como uma unidade independente, facilitando a manutenção e a evolução do sistema ao longo do tempo.

 

Componentes do Padrão State

Context (Contexto): É a classe que possui um estado interno variável. O contexto mantém uma referência para uma instância de um estado concreto e encaminha todas as solicitações para o estado atual.

State (Estado): É uma interface que define os métodos que encapsulam o comportamento associado a um estado particular do contexto. Cada estado concreto implementa essa interface.

ConcreteState (Estado Concreto): São as classes que implementam a interface State. Cada classe representa um estado específico do contexto e define o comportamento correspondente.

 

Benefícios do Padrão State

Flexibilidade: O padrão State permite que objetos alterem seu comportamento dinamicamente, sem alterar sua estrutura interna. Isso torna o código mais flexível e adaptável a mudanças nos requisitos.

Organização: Ao dividir o comportamento em classes de estado separadas, o padrão promove uma melhor organização do código. Cada estado é encapsulado em sua própria classe, tornando o código mais claro e fácil de entender.

Manutenção: Como o comportamento relacionado a cada estado é isolado em classes separadas, a manutenção do código se torna mais fácil. Alterações no comportamento de um estado não afetam diretamente os outros estados ou o contexto.

 

Exemplo de aplicação:

Interface Estado (State):

  • A interface Estado define os métodos que representam as ações que podem ser executadas em cada estado da máquina de venda automática, como inserir moeda, selecionar produto e dispensar produto.

Classes de Estado Concreto:

  • As classes EstadoSemMoeda e EstadoComMoeda são exemplos de estados concretos da máquina. Cada uma implementa a interface Estado e define o comportamento correspondente ao estado em que a máquina se encontra. Por exemplo, o EstadoSemMoeda permite apenas a inserção de moeda, enquanto o EstadoComMoeda permite a seleção e a dispensa do produto.

 

 

Classe Contexto (MaquinaVenda):

  • A classe MaquinaVenda é o contexto da máquina de venda automática, que mantém uma referência para o estado atual. Ela possui métodos para executar as ações disponíveis na máquina, como inserirMoeda, selecionarProduto e dispensarProduto.
  • As transições de estado são realizadas através do método setState na classe MaquinaVenda. Quando uma moeda é inserida no estado SemMoeda, a máquina transita para o estado ComMoeda, e vice-versa quando um produto é dispensado.

 

 

Exemplo de Uso:

  • No exemplo de uso na classe Principal, criamos uma instância da MaquinaVenda e realizamos uma sequência de ações, como selecionar um produto após inserir uma moeda. Cada ação gera uma saída correspondente, demonstrando o comportamento da máquina de acordo com seu estado atual.

 

 

Dessa forma, o padrão State permite que o comportamento da máquina de venda automática seja representado de forma modular e flexível, com cada estado encapsulando seu próprio conjunto de comportamentos e ações. Isso torna o código mais fácil de entender, manter e expandir à medida que novos estados e funcionalidades são adicionados.

 

Fontes:

https://refactoring.guru/design-patterns/state

https://www.youtube.com/watch?v=tSTPS2oHDmw

https://www.youtube.com/watch?v=a1JoummFS04&t=1015s

Escrito por:

Está gostando do conteúdo? Compartilhe!

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Artigos Recentes

Como a Transformação Digital Está Moldando o Futuro dos Negócios

A transformação digital não é mais uma opção, mas uma necessidade para empresas que desejam se manter competitivas no mercado atual. À medida que a tecnologia avança rapidamente, empresas de todos os setores estão adotando soluções digitais para melhorar suas operações, aumentar a eficiência e oferecer melhores experiências aos clientes.

Leia Mais »

MongoDB: uma introdução ao mundo NoSQL

  No contexto de tecnologias, é importante sempre ter em mente duas características fundamentais da área: Primeiramente, quando uma tecnologia é bem aplicada e obtém sucesso, há uma tendência de expansão do seu uso, com isso, mais explorada e desenvolvida,  naturalmente as aplicações exigem cada vez mais dessa tecnologia. Em

Leia Mais »

Python: Analisando Dados E Criando Gráficos

  Nos últimos anos, a análise de dados tornou-se um dos pilares fundamentais das estratégias de grandes empresas em todo o mundo. À medida que a quantidade de informações disponíveis continua a crescer exponencialmente, a capacidade de extrair insights significativos desses dados se tornou uma vantagem competitiva crucial. Nesse contexto, a linguagem

Leia Mais »

Dominando os recursos de relacionamentos eloquent do Laravel

Introdução Nos bastidores de qualquer aplicativo Laravel poderoso está o Eloquent ORM, uma ferramenta que não só simplifica drasticamente a interação com o banco de dados, mas também abre as portas para uma arquitetura de aplicativos mais organizada e flexível. Entre os vários tesouros que o Eloquent oferece, destaca-se o

Leia Mais »

Sobre o Autor

Mais sobre tecnologia

Gostou do Artigo?

Recebemos sua Assinatura com Sucesso!

Obrigado por assinar nossa newsletter!

Enviamos um e-mail para você confirmar sua assinatura, assim que confirmar passará a receber novidades em tecnologia da Rem Soft Sistemas.

Lembre-se sempre se caso não receber nosso e-mail na caixa de entrada,
Observe sua caixa de spam em seu e-mail.