🚀 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.

  1. Contexto: É a classe principal (Ex: O Personagem). Ela mantém uma referência para o estado atual.
  2. Estado (Interface): Define os métodos comuns a todos os estados.
  3. Estados Concretos: As classes que implementam o comportamento específico de cada estado (Ex: Classe EstadoJekyll e EstadoHyde).

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.

  1. Crie a classe para esse novo estado e defina o que o personagem diria no método falar().
  2. 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)

  1. Faça o Commit: No GitHub Desktop, digite a mensagem (ex: Finaliza Capítulo 18 Paradigmas) e clique em Commit to main.
  2. 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.js

9. 💡 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:

  1. Classe:
class EstadoComMedo extends Estado {
    falar() { return "Por favor, não me machuque!"; }
}
  1. Aplicação: drJekyll.mudarEstado(new EstadoComMedo());

Capitulo Anterior | Proximo Capitulo