🚀 Capítulo 18: State (Tema: Dr. Jekyll and Mr. Hyde)
NOTE
Este capítulo utiliza a temática de O Médico e o Monstro para explicar o padrão State. O mesmo personagem se comporta de forma totalmente diferente dependendo do seu estado interno!
1. 🎯 Objetivo da Aula
Compreender o padrão de projeto State (Padrão Comportamental), entendendo como ele permite que um objeto altere seu comportamento quando seu estado interno muda, parecendo que o objeto mudou de classe.
2. 🏢 O Cenário Prático (Seu Desafio)
Você está programando um jogo baseado no clássico livro “O Médico e o Monstro”.
- O personagem principal é o cientista.
- Quando ele está no estado Dr. Jekyll (Normal), ele é educado. O método
falar()retorna"Olá, cavalheiro. Como posso ajudar?". - Quando ele toma a poção e passa para o estado Mr. Hyde (Monstro), ele fica agressivo. O mesmo método
falar()agora retorna"GRRR! SAIA DA MINHA FRENTE!".
Se usarmos um monte de if/else dentro da classe Personagem para verificar em qual estado ele está toda vez que chamamos um método, o código ficará feio e difícil de manter.
O padrão State diz: crie uma classe para o estado “Normal” e outra para o estado “Monstro”! O personagem apenas delega a ação para a classe do estado atual.
Seu desafio é gerenciar essa dupla personalidade!
3. 🧠 Fundamentos: A Teoria Traduzida
O State (Estado) é um padrão de projeto comportamental que permite que um objeto altere seu comportamento quando seu estado interno muda. O objeto parecerá ter mudado de classe.
🎭 Máquina de Estados
O padrão State é a implementação orientada a objetos de uma Máquina de Estados Finita.
- Contexto: É a classe principal (Ex: O Personagem). Ela mantém uma referência para o estado atual.
- Estado (Interface): Define os métodos comuns a todos os estados.
- Estados Concretos: As classes que implementam o comportamento específico de cada estado (Ex: Classe
EstadoJekylleEstadoHyde).
4. 📖 Exemplo Guiado: A Transformação (JS)
// INTERFACE DE ESTADO (Conceitual)
class Estado {
falar() {}
}
// ESTADOS CONCRETOS
class EstadoJekyll extends Estado {
falar() { return "Olá, cavalheiro. Como posso ajudar?"; }
}
class EstadoHyde extends Estado {
falar() { return "GRRR! SAIA DA MINHA FRENTE!"; }
}
// O CONTEXTO (O Personagem)
class Personagem {
constructor() {
this.estado = new EstadoJekyll(); // Começa como Jekyll
}
mudarEstado(novoEstado) { this.estado = novoEstado; }
falar() {
// Delega o comportamento para o estado atual!
console.log(this.estado.falar());
}
}
// USO
const drJekyll = new Personagem();
drJekyll.falar(); // "Olá, cavalheiro..."
// Tomando a poção
console.log("\n*Bebendo a poção...*\n");
drJekyll.mudarEstado(new EstadoHyde());
drJekyll.falar(); // "GRRR! SAIA DA MINHA FRENTE!"5. 🛠️ Prática Obrigatória 1: Personagem com Medo
Imagine que queremos adicionar um terceiro estado: EstadoComMedo.
- Crie a classe para esse novo estado e defina o que o personagem diria no método
falar(). - Como faríamos no código para o personagem mudar para esse novo estado?
6. 🛠️ Prática Obrigatória 2: State vs Strategy
O padrão State parece idêntico ao padrão Strategy (Capítulo anterior). Ambos usam composição para mudar o comportamento. Mas há uma diferença de intenção:
- No Strategy, o usuário geralmente escolhe a estratégia ativamente (Ex: escolhe pagar com Pix).
- No State, os próprios estados podem fazer o objeto mudar para outro estado automaticamente (Ex: Ao tomar dano, o personagem passa do estado “Forte” para o estado “Fraco”). Dê um exemplo de um objeto do seu dia a dia que muda de estado sozinho (Ex: Um semáforo de trânsito).
7. 📤 Instruções de Entrega (GitHub Desktop + Microsoft Teams)
- Faça o Commit: No GitHub Desktop, digite a mensagem (ex:
Finaliza Capítulo 18 Paradigmas) e clique em Commit to main. - Envie para a Nuvem (Push): Clique em Push origin.
8. 📂 Estrutura de Pastas
mod_10_paradigmas_e_padroes_de_projeto/
├── capitulos/
│ ├── capitulo_18_state.md
│ └── codigos/
│ └── cap18/
│ └── medico_monstro.js9. 💡 Checkpoint de Lógica
O padrão State elimina os grandes blocos condicionais (switch ou if/else) que dependem do estado do objeto, espalhando a lógica em classes menores e focadas.
10. 🔥 Desafio de Fixação
Pesquise como o padrão State é usado para controlar o fluxo de um Carrinho de Compras (Estados: Vazio, PreenchendoDados, Pago, Enviado).
🔑 Gabarito de Código/Fórmulas
Gabarito da Prática 1:
- Classe:
class EstadoComMedo extends Estado {
falar() { return "Por favor, não me machuque!"; }
}- Aplicação:
drJekyll.mudarEstado(new EstadoComMedo());