Menu
Coddy logo textTech

Patrón Command

Parte de la sección Programación Orientada a Objetos del Journey de PHP de Coddy — lección 75 de 91.

El Patrón Command es un patrón de diseño de comportamiento que convierte una solicitud en un objeto independiente que contiene toda la información sobre la solicitud. Esta transformación te permite pasar solicitudes como argumentos de método, retrasar o poner en cola la ejecución de una solicitud y admitir operaciones que se pueden deshacer.

Piensa en un restaurante.

Cuando pides comida, el camarero escribe tu pedido en una nota (el comando), la lleva a la cocina y el chef la ejecuta. El camarero no necesita saber cocinar; simplemente entrega el comando.

Esto desacopla al solicitante del ejecutor.

Aquí tienes una implementación básica:

<?php
interface Command {
    public function execute(): string;
}
class Light {
    public function on(): string { return "Light is ON"; }
    public function off(): string { return "Light is OFF"; }
}
class LightOnCommand implements Command {
    public function __construct(private Light $light) {}
    
    public function execute(): string {
        return $this->light->on();
    }
}
class LightOffCommand implements Command {
    public function __construct(private Light $light) {}
    
    public function execute(): string {
        return $this->light->off();
    }
}

El invocador activa comandos sin saber qué hacen:

<?php
class RemoteControl {
    public function press(Command $command): string {
        return $command->execute();
    }
}
$light = new Light();
$remote = new RemoteControl();

echo $remote->press(new LightOnCommand($light)) . "\n";
echo $remote->press(new LightOffCommand($light));

Resultado:

Light is ON
Light is OFF

El patrón Command sobresale cuando necesitas poner operaciones en cola, implementar la funcionalidad de deshacer o registrar acciones. Cada comando es autónomo, lo que facilita la adición de nuevos comandos sin modificar el código existente.

challenge icon

Desafío

Fácil

Vamos a construir un sistema de comandos para un editor de texto utilizando el Patrón Command. Los editores de texto a menudo necesitan soportar operaciones como escribir texto, borrar texto y deshacer acciones; cada operación se convierte en un objeto de comando autónomo que puede ejecutarse a través de una interfaz unificada.

Organizarás tu código en cuatro archivos:

  • Command.php — Define una interfaz Command con un único método execute(): string. Esto establece el contrato que todos los comandos del editor deben seguir.
  • TextEditor.php — Crea una clase TextEditor que represente al receptor: el objeto que realmente realiza el trabajo. Tu editor debe:
    • Almacenar el contenido de texto actual (comienza con una cadena vacía)
    • Tener un método write(string $text): string que añada texto al contenido y devuelva "Written: [text]"
    • Tener un método clear(): string que vacíe el contenido y devuelva "Content cleared"
    • Tener un método getContent(): string que devuelva el contenido actual
  • Commands.php — Incluye los archivos Command y TextEditor. Crea dos clases de comando que implementen la interfaz Command:
    • WriteCommand — Recibe un TextEditor y una cadena de texto en su constructor. Su método execute() llama al método write() del editor y devuelve el resultado.
    • ClearCommand — Recibe un TextEditor en su constructor. Su método execute() llama al método clear() del editor y devuelve el resultado.
  • main.php — Incluye el archivo Commands. Recibirás dos entradas: un tipo de comando ("write" o "clear") y una cadena de texto (utilizada solo para los comandos de escritura).

    Crea una instancia de TextEditor. Basándote en el tipo de comando, crea el objeto de comando apropiado. Luego, crea una función invocadora o un mecanismo simple que llame a execute() en el comando e imprima el resultado.

    En una nueva línea, imprime el contenido actual del editor en este formato: Content: [content] (si está vacío, simplemente imprime Content: sin nada después del espacio).

Este desafío demuestra cómo el Patrón Command encapsula cada operación como un objeto. El invocador no necesita saber si está ejecutando un comando de escritura o de limpieza; simplemente llama a execute() y deja que el comando maneje los detalles.

Hoja de referencia

El Patrón Command es un patrón de diseño de comportamiento que encapsula una solicitud como un objeto independiente que contiene toda la información sobre la misma. Esto permite pasar solicitudes como argumentos de método, poner operaciones en cola y admitir acciones que se pueden deshacer.

El patrón desacopla al solicitante (invocador) del ejecutor (receptor), de manera similar a cómo un camarero entrega los pedidos a un chef sin necesidad de saber cocinar.

Estructura Básica

Define una interfaz Command con un método execute():

interface Command {
    public function execute(): string;
}

Crea una clase receptora que realice el trabajo real:

class Light {
    public function on(): string { return "Light is ON"; }
    public function off(): string { return "Light is OFF"; }
}

Implementa clases de comando concretas que encapsulen acciones específicas:

class LightOnCommand implements Command {
    public function __construct(private Light $light) {}
    
    public function execute(): string {
        return $this->light->on();
    }
}

class LightOffCommand implements Command {
    public function __construct(private Light $light) {}
    
    public function execute(): string {
        return $this->light->off();
    }
}

Invocador

El invocador activa los comandos sin conocer los detalles de su implementación:

class RemoteControl {
    public function press(Command $command): string {
        return $command->execute();
    }
}

$light = new Light();
$remote = new RemoteControl();

echo $remote->press(new LightOnCommand($light)) . "\n";
echo $remote->press(new LightOffCommand($light));

Beneficios

El Patrón Command es ideal para poner operaciones en cola, implementar la funcionalidad de deshacer o registrar acciones. Cada comando es autónomo, lo que facilita la adición de nuevos comandos sin modificar el código existente.

Pruébalo tú mismo

<?php

require_once 'Commands.php';

// Leer entrada
$commandType = trim(fgets(STDIN)); // "write" o "clear"
$text = trim(fgets(STDIN));         // texto para el comando write

// TODO: Crear una instancia de TextEditor

// TODO: Basado en el tipo de comando, crear el objeto de comando apropiado
// - Si es "write", crear un WriteCommand con el editor y el texto
// - Si es "clear", crear un ClearCommand con el editor

// TODO: Crear un mecanismo invocador que llame a execute() en el comando
// y que imprima el resultado

// TODO: Imprimir el contenido actual del editor en el formato: "Content: [content]"
// (si está vacío, simplemente imprimir "Content: " sin nada después del espacio)

?>
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos