Patron Commande
Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy. Leçon 75 sur 91.
Le pattern Command est un patron de conception comportemental qui transforme une requête en un objet autonome contenant toutes les informations sur la requête. Cette transformation vous permet de transmettre des requêtes en tant qu’arguments de méthode, de retarder ou de mettre en file d’attente l’exécution d’une requête, et de prendre en charge les opérations pouvant être annulées.
Pense à un restaurant.
Lorsque vous commandez à manger, le serveur écrit votre commande sur un bon (la commande), l’apporte en cuisine et le chef l’exécute. Le serveur n’a pas besoin de savoir cuisiner : il lui suffit de transmettre la commande.
Cela découple le demandeur de l’exécuteur.
Voici une implémentation de base :
<?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();
}
}
L’invocateur déclenche des commandes sans savoir ce qu’elles font :
<?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));
Sortie :
Light is ON
Light is OFFLe modèle Command est particulièrement adapté lorsque vous devez mettre des opérations en file d’attente, implémenter une fonctionnalité d’annulation ou journaliser des actions. Chaque commande est autonome, ce qui facilite l’ajout de nouvelles commandes sans modifier le code existant.
Défi
FacileConstruisons un système de commandes pour un éditeur de texte en utilisant le modèle Command. Les éditeurs de texte doivent souvent prendre en charge des opérations telles que l’écriture de texte, la suppression de texte et l’annulation d’actions : chaque opération devient un objet commande autonome pouvant être exécuté via une interface unifiée.
Vous organiserez votre code sur quatre fichiers :
Command.php: définissez une interfaceCommandavec une seule méthodeexecute(): string. Cela établit le contrat que toutes les commandes de l’éditeur doivent respecter.TextEditor.php: créez une classeTextEditorqui représente le récepteur, c’est-à-dire l’objet qui effectue réellement le travail. Votre éditeur doit :- Stocker le contenu textuel actuel (en commençant par une chaîne vide)
- Posséder une méthode
write(string $text): stringqui ajoute du texte au contenu et renvoie"Written: [text]" - Posséder une méthode
clear(): stringqui vide le contenu et renvoie"Content cleared" - Posséder une méthode
getContent(): stringqui renvoie le contenu actuel
Commands.php: incluez les fichiers Command et TextEditor. Créez deux classes de commandes qui implémentent l’interfaceCommand:WriteCommand: reçoit unTextEditoret une chaîne de texte dans son constructeur. Sa méthodeexecute()appelle la méthodewrite()de l’éditeur et renvoie le résultat.ClearCommand: reçoit unTextEditordans son constructeur. Sa méthodeexecute()appelle la méthodeclear()de l’éditeur et renvoie le résultat.
main.php: incluez le fichier Commands. Vous recevrez deux entrées : un type de commande ("write"ou"clear") et une chaîne de texte (utilisée uniquement pour les commandes d’écriture).Créez une instance de
TextEditor. Selon le type de commande, créez l’objet commande approprié. Créez ensuite une fonction invocatrice ou un mécanisme simple qui appelleexecute()sur la commande et affiche le résultat.Sur une nouvelle ligne, affichez le contenu actuel de l’éditeur dans ce format :
Content: [content](s’il est vide, affichez simplementContent:sans rien après l’espace).
Ce défi montre comment le modèle Command encapsule chaque opération sous la forme d’un objet. L’invocateur n’a pas besoin de savoir s’il exécute une commande d’écriture ou d’effacement. Il appelle simplement execute() et laisse la commande gérer les détails.
Essayez vous-même
<?php
require_once 'Commands.php';
// Lire l'entrée
$commandType = trim(fgets(STDIN)); // "write" ou "clear"
$text = trim(fgets(STDIN)); // texte pour la commande write
// TODO: Créer une instance de TextEditor
// TODO: En fonction du type de commande, créer l'objet commande approprié
// - Si "write", créer un WriteCommand avec l'éditeur et le texte
// - Si "clear", créer un ClearCommand avec l'éditeur
// TODO: Créer un mécanisme d'invoker qui appelle execute() sur la commande
// et affiche le résultat
// TODO: Afficher le contenu actuel de l'éditeur au format : "Content: [content]"
// (si vide, afficher simplement "Content: " sans rien après l'espace)
?>Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses et objetsLe mot-clé $thisMéthodesPropriétésConstructeur (__construct)Destructeur (__destruct)Récapitulatif - Calculatrice simple4Héritage
Héritage de baseLe mot-clé parent::Redéfinition des méthodesLe mot-clé finalClasses abstraitesRécapitulatif – Hiérarchie des employés7Encapsulation
Public, Protected, PrivateModificateurs d’accès en profondeurAccesseurs et mutateursDissimulation de l’informationPromotion des constructeurs (8.0)Récapitulatif – Système de fiches étudiant10Concepts avancés de la POO
Composition ou héritageInjection de dépendancesClasses anonymesÉnumérations (PHP 8.1)Fibres (PHP 8.1)Approfondissement du clonage d’objetsGénérateurs et itérateurs13Patrons de conception – Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode modèlePatron ÉtatPatron CompositePatron Dépôt2Espaces de noms et chargement automatique
Introduction aux espaces de nomsLe mot-clé useNorme de chargement automatique PSR-4Autoloader de ComposerRécapitulatif - Projet organisé5Interfaces et contrats
Introduction aux interfacesImplémentation des interfacesImplémentation de plusieurs interfacesInterface ou classe abstraiteIndication de type avec les interfacesRécapitulatif - Calculateur de formes8Méthodes magiques
Introduction aux méthodes magiques__toString et __debugInfo__get, __set, __isset, __unset__call et __callStatic__clone et clonage d’objets__serialize et __unserializeRécapitulatif - Collection personnalisée3Propriétés de classe
Propriétés d’instance vs statiquesConstantes dans les classesMéthodes et propriétés statiquesPropriétés privées et protégéesPropriétés en lecture seule (PHP 8.1)Récapitulatif - Gestionnaire de comptes bancaires6Polymorphisme
Révision de la redéfinition des méthodesPolymorphisme via les interfacesAnnotations de type et types unionLiaison statique tardiveRécapitulatif - Processeur de paiements9Traits
Introduction aux traitsUtilisation de plusieurs traitsRésolution des conflits entre traitsMéthodes abstraites dans les traitsTraits par rapport à l’héritage12Patrons de conception – Partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FactoryPatron ObserverPatron StrategyEntraînez-vous par vous-même : Compilateur PHP en ligne