O padrão State é um padrão de design comportamental que tem como objetivo principal permitir que um objeto altere seu comportamento quando o seu estado interno muda. O padrão State resolve uma série de problemas relacionados ao gerenciamento de estados e comportamentos em sistemas orientados a objetos:
-
Eliminação de Condicionais Complexas: Em sistemas onde o comportamento de um objeto depende de seu estado e existe uma complexa estrutura condicional (
ifouswitch) para controlar essas mudanças, o padrão State encapsula os comportamentos associados a cada estado em classes separadas, simplificando assim o código e tornando-o mais fácil de manter. -
Encapsulamento do Estado Específico: Ao separar os comportamentos específicos de cada estado em classes diferentes, o padrão State promove um melhor encapsulamento e organiza o código de forma mais clara.
-
Transições de Estado Facilitadas: Facilita a transição entre estados, já que as mudanças de estado implicam na substituição de um objeto de estado por outro, ao invés de alterar muitos atributos internos.
-
Extensibilidade: Novos estados e comportamentos podem ser adicionados facilmente sem alterar os estados existentes, tornando o sistema mais extensível.
Como Funciona
O padrão State envolve geralmente três componentes principais:
- Contexto: Classe que possui um estado atual. Ela mantém uma referência a um objeto de estado que representa seu estado atual e delega as solicitações de comportamento para esse objeto.
- State (Interface ou Classe Abstrata): Define uma interface para encapsular o comportamento associado a um determinado estado do Contexto.
- Concrete States: Classes que implementam a interface State. Cada classe representa um estado específico do Contexto e contém o comportamento específico para esse estado.
Exemplo
Um exemplo clássico do uso do padrão State é em uma máquina de venda automática ou em um jogo, onde o objeto pode ter estados como 'sem moeda', 'com moeda', 'item selecionado', etc. Cada estado tem comportamentos diferentes (por exemplo, inserir moeda, selecionar item, entregar item) e o objeto muda seu comportamento de acordo com o estado atual.
Exemplo de Implementação
Vamos criar um exemplo simples do padrão State em Java. Vamos desenvolver um sistema básico para um semáforo que altera seu estado entre verde, amarelo e vermelho.
Interface State
Primeiro, definimos a interface State, que será implementada por todos os estados:
public interface State {
void handle(Semaforo semaforo);
}Estados Concretos
Implementamos os estados concretos para o semáforo:
public class Verde implements State {
@Override
public void handle(Semaforo semaforo) {
System.out.println("Luz verde: Pode passar");
semaforo.setState(new Amarelo());
}
}
public class Amarelo implements State {
@Override
public void handle(Semaforo semaforo) {
System.out.println("Luz amarela: Atenção");
semaforo.setState(new Vermelho());
}
}
public class Vermelho implements State {
@Override
public void handle(Semaforo semaforo) {
System.out.println("Luz vermelha: Pare");
semaforo.setState(new Verde());
}
}Contexto
Agora, criamos a classe Semaforo que é o contexto. Ela mantém uma referência ao estado atual e permite sua mudança:
public class Semaforo {
private State estadoAtual;
public Semaforo(State estadoInicial) {
this.estadoAtual = estadoInicial;
}
public void setState(State estado) {
this.estadoAtual = estado;
}
public void change() {
estadoAtual.handle(this);
}
}Testando o Padrão State
Por fim, usamos o padrão State para controlar o semáforo:
public class Main {
public static void main(String[] args) {
Semaforo semaforo = new Semaforo(new Verde());
// Estado inicial: Verde
semaforo.change(); // Muda para Amarelo
// Estado atual: Amarelo
semaforo.change(); // Muda para Vermelho
// Estado atual: Vermelho
semaforo.change(); // Muda para Verde novamente
}
}
Neste exemplo, a classe Semaforo é configurada com um estado inicial (Verde) e a cada chamada do método change(), o estado do semáforo muda e o comportamento associado a esse estado é executado. Isso demonstra como o padrão State permite a um objeto mudar seu comportamento dinamicamente de acordo com seu estado interno, mantendo o código organizado e facilitando a adição de novos estados.
Padrão State e State Machine
O padrão State é uma forma de implementar uma máquina de estados em um contexto de programação orientada a objetos, focando na maneira como o comportamento de um objeto pode ser alterado dinamicamente conforme ele muda de estado. As máquinas de estados, por outro lado, são um conceito mais amplo e podem ser implementadas de várias maneiras, dependendo do contexto e das necessidades específicas do sistema.