🚨 ¡Nueva review! ¡Mi teclado ideal! ⌨️ Perfecto para programar, el Logitech MX Keys S . ¡Échale un ojo! 👀

El Patrón de diseño State

Cuando tu objeto tiene cambios de humor.

Escrito por domin el 25 de noviembre de 2025

🚦 El Patrón State: El Camaleón

El patrón de diseño State permite que un objeto modifique su comportamiento cuando su estado interno cambia. Parece como si el objeto cambiara de clase.

El problema que resuelve es este:
¿Cómo gestionas un objeto que reacciona de forma totalmente distinta a los mismos eventos dependiendo de en qué estado se encuentre, sin llenar tu código de if ($estado == 'A') ... elseif ($estado == 'B')?

La respuesta es encapsular cada estado en una clase propia y delegar el comportamiento al objeto de estado actual.

Diagrama del Patrón State.

📱 1. Un ejemplo sencillo: tu teléfono móvil

Imagina tu móvil y el botón de “Home” (el contexto):

  1. Estado desbloqueado: Si pulsas Home, vas a la pantalla de inicio.
  2. Estado bloqueado: Si pulsas Home, se enciende la pantalla para pedirte la clave.
  3. Estado sin batería: Si pulsas Home, no pasa nada (o sale el icono de batería baja).

El botón es el mismo, pero la reacción depende del Estado.

Concepto (Analogía)

Rol en State

Tarea Principal

El Móvil

Contexto

Mantiene una referencia al estado actual y delega en él.

Bloqueado / Desbloqueado

Estados Concretos

Implementan la lógica específica para ese estado.

🛠️ 2. Los tres pilares del patrón State

1. Contexto

2. Interfaz Estado

3. Estados Concretos

🤔 1. ¿Quién es responsable de realizar la transición de un estado a otro?

🚦 3. El ejemplo clásico: Máquina de estados

Cualquier proceso con fases: Pedidos (Pendiente -> Pagado -> Enviado), Semáforos (Verde -> Ambar -> Rojo), o Personajes de juegos (Normal -> Super Mario -> Mario de Fuego).

🤔 2. ¿En qué se diferencia State de Strategy?

✅ 4. ¿Por qué usarlo?

  1. Adiós a los IFs: Eliminas esas máquinas de estado monolíticas basadas en condicionales.
  2. Organización: Cada estado tiene su propia clase. Es fácil añadir estados nuevos.

❌ 5. Desventaja a considerar

🤔 3. ¿Qué pasa si añades un nuevo método a la Interfaz de Estado?

💡 6. Conclusión

El State es perfecto para objetos que cambian de “personalidad” en tiempo de ejecución. Hace que el código sea dinámico y fácil de extender.

🧠 7. Ejemplo práctico en PHP

Vamos a implementar un Reproductor de Música.

<?php

// 🔹 1. Interfaz Estado
interface EstadoAudio
{
    public function clickPlay(Reproductor $reproductor): void;
}

// 🔹 2. Contexto
class Reproductor
{
    private EstadoAudio $estado;

    public function __construct(EstadoAudio $estadoInicial)
    {
        $this->cambiarEstado($estadoInicial);
    }

    public function cambiarEstado(EstadoAudio $estado): void
    {
        $this->estado = $estado;
        echo "🔄 Estado cambiado a: " . get_class($estado) . "\n";
    }

    public function clickPlay(): void
    {
        $this->estado->clickPlay($this);
    }
}

// 🔹 3. Estados Concretos
class EstadoListo implements EstadoAudio
{
    public function clickPlay(Reproductor $reproductor): void
    {
        echo "▶️ Reproduciendo música...\n";
        $reproductor->cambiarEstado(new EstadoReproduciendo());
    }
}

class EstadoReproduciendo implements EstadoAudio
{
    public function clickPlay(Reproductor $reproductor): void
    {
        echo "⏸️ Pausando música...\n";
        $reproductor->cambiarEstado(new EstadoListo());
    }
}

class EstadoBloqueado implements EstadoAudio
{
    public function clickPlay(Reproductor $reproductor): void
    {
        echo "🚫 El reproductor está bloqueado. Desbloquéalo primero.\n";
        // No cambia de estado
    }
}

// 🔹 4. Uso
$reproductor = new Reproductor(new EstadoListo());

echo "--- Click 1 ---\n";
$reproductor->clickPlay(); // Pasa a Reproduciendo

echo "\n--- Click 2 ---\n";
$reproductor->clickPlay(); // Pasa a Listo (Pausa)

echo "\n--- Bloqueamos el reproductor (simulado) ---\n";
$reproductor->cambiarEstado(new EstadoBloqueado());

echo "\n--- Click 3 ---\n";
$reproductor->clickPlay(); // No hace nada

// 🖥️ Salida:
// 🔄 Estado cambiado a: EstadoListo
// --- Click 1 ---
// ▶️ Reproduciendo música...
// 🔄 Estado cambiado a: EstadoReproduciendo
//
// --- Click 2 ---
// ⏸️ Pausando música...
// 🔄 Estado cambiado a: EstadoListo
//
// --- Bloqueamos el reproductor (simulado) ---
// 🔄 Estado cambiado a: EstadoBloqueado
//
// --- Click 3 ---
// 🚫 El reproductor está bloqueado. Desbloquéalo primero.

EA, ¡saluditos y nos vemos en los bares! 🍻