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étodos, 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), lo lleva a la cocina y el chef lo ejecuta. El camarero no necesita saber cocinar; solo 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));
Salida:
Light is ON
Light is OFFEl 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 añadir nuevos comandos sin modificar el código existente.
Desafío
FácilConstruyamos un sistema de comandos para un editor de texto utilizando el patrón Command. Los editores de texto a menudo necesitan admitir operaciones como escribir texto, eliminar texto y deshacer acciones: cada operación se convierte en un objeto de comando independiente que se puede ejecutar a través de una interfaz unificada.
Organizarás tu código en cuatro archivos:
Command.php: Define una interfazCommandcon un único métodoexecute(): string. Esto establece el contrato que deben seguir todos los comandos del editor.TextEditor.php, Crea una claseTextEditorque 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): stringque añada texto al contenido y devuelva"Written: [text]" - Tener un método
clear(): stringque vacíe el contenido y devuelva"Content cleared" - Tener un método
getContent(): stringque devuelva el contenido actual
Commands.php: Incluye los archivos Command y TextEditor. Crea dos clases de comandos que implementen la interfazCommand:WriteCommand: Recibe unTextEditory una cadena de texto en su constructor. Su métodoexecute()llama al métodowrite()del editor y devuelve el resultado.ClearCommand: Recibe unTextEditoren su constructor. Su métodoexecute()llama al métodoclear()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. Según el tipo de comando, crea el objeto de comando apropiado. Después, crea una función invocadora o un mecanismo sencillo que llame aexecute()en el comando e imprima el resultado.En una línea nueva, imprime el contenido actual del editor con este formato:
Content: [content](si está vacío, imprime simplementeContent: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 permite que el comando gestione los detalles.
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: Crea una instancia de TextEditor
// TODO: Basado en el tipo de comando, crea el objeto de comando apropiado
// - Si "write", crea un WriteCommand con el editor y el texto
// - Si "clear", crea un ClearCommand con el editor
// TODO: Crea un mecanismo invocador que llame a execute() en el comando
// e imprime el resultado
// TODO: Imprime el contenido actual del editor en el formato: "Content: [content]"
// (si está vacío, solo imprime "Content: " sin nada después del espacio)
?>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
1Fundamentos de la POO
Archivos externosIntroducción a la POOClases frente a objetosLa palabra clave $thisMétodosPropiedadesConstructor (__construct)Destructor (__destruct)Repaso: calculadora simple4Herencia
Herencia básicaLa palabra clave parent::Sobrescritura de métodosLa palabra clave finalClases abstractasRepaso - Jerarquía de empleados7Encapsulación
Público, protegido, privadoModificadores de acceso en profundidadGetters y settersOcultación de la informaciónPromoción del constructor (8.0)Repaso: sistema de registros de estudiantes10Conceptos avanzados de OOP
Composición vs. herenciaInyección de dependenciasClases anónimasEnums (PHP 8.1)Fibras (PHP 8.1)Análisis profundo de la clonación de objetosGeneradores e iteradores13Patrones de diseño Parte 2
Patrón CommandPatrón AdapterPatrón DecoratorPatrón Template MethodPatrón StatePatrón CompositePatrón Repository2Namespaces y carga automática
Introducción a los NamespacesLa palabra clave useEstándar de carga automática PSR-4Autoloader de ComposerRepaso: proyecto organizado5Interfaces y contratos
Introducción a las interfacesImplementación de interfacesImplementación de múltiples interfacesInterfaces vs. clase abstractaTipado con interfacesRepaso - Calculadora de formas8Métodos mágicos
Introducción a los métodos mágicos__toString y __debugInfo__get, __set, __isset, __unset__call y __callStatic__clone y clonación de objetos__serialize y __unserializeRepaso: colección personalizada3Propiedades de clase
Propiedades de instancia vs. estáticasConstantes en clasesMétodos y propiedades estáticosPropiedades privadas y protegidasPropiedades de solo lectura (PHP 8.1)Repaso: gestor de cuentas bancarias6Polimorfismo
Repaso de la sobrescritura de métodosPolimorfismo mediante interfacesAnotaciones de tipo y tipos uniónEnlace estático tardíoRepaso: procesador de pagos9Traits
Introducción a los TraitsUso de múltiples TraitsResolución de conflictos entre TraitsMétodos abstractos en TraitsTraits frente a la herencia12Patrones de diseño, parte 1
Introducción a los patrones de diseñoPatrón SingletonPatrón FactoryPatrón ObserverPatrón StrategyPractica por tu cuenta: Compilador de PHP online