Patron Commande
Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy. Leçon 56 sur 70.
Le patron Commande est un patron de conception comportemental qui transforme une requête en un objet autonome contenant toutes les informations relatives à celle-ci. Cette transformation vous permet de passer des requêtes comme arguments de méthode, de les mettre en file d'attente, de les journaliser ou de prendre en charge des opérations annulables.
Le modèle sépare l’objet qui invoque une opération de l’objet qui sait comment l’exécuter. Il se compose de quatre éléments clés : une interface de commande, des commandes concrètes, un récepteur (l’objet qui effectue le travail réel) et un invocateur (l’objet qui déclenche les commandes).
public interface ICommand
{
void Execute();
}
public class Light // Récepteur
{
public void TurnOn() => Console.WriteLine("Light is ON");
public void TurnOff() => Console.WriteLine("Light is OFF");
}
public class TurnOnCommand : ICommand
{
private Light _light;
public TurnOnCommand(Light light) => _light = light;
public void Execute() => _light.TurnOn();
}
public class TurnOffCommand : ICommand
{
private Light _light;
public TurnOffCommand(Light light) => _light = light;
public void Execute() => _light.TurnOff();
}L'invocateur stocke et exécute des commandes sans savoir ce qu'elles font :
public class RemoteControl // Invocateur
{
private ICommand _command;
public void SetCommand(ICommand command) => _command = command;
public void PressButton() => _command.Execute();
}
// Utilisation
var light = new Light();
var remote = new RemoteControl();
remote.SetCommand(new TurnOnCommand(light));
remote.PressButton(); // La lumière est ALLUMÉE
remote.SetCommand(new TurnOffCommand(light));
remote.PressButton(); // La lumière est ÉTEINTELe modèle Command est particulièrement puissant pour implémenter la fonctionnalité d’annulation, l’enregistrement de macros ou la mise en file d’attente d’opérations pour une exécution ultérieure. Chaque commande encapsule tout ce qui est nécessaire pour effectuer une action, ce qui rend votre système plus flexible et extensible.
Défi
FacileConstruisons un système de commandes pour un éditeur de texte en utilisant le modèle Command. Tu vas créer un système dans lequel les opérations d’édition, comme l’insertion et la suppression de texte, sont encapsulées sous forme d’objets commande, ce qui permet à l’éditeur de les exécuter via une interface unifiée.
Tu organiseras ton code dans trois fichiers :
Command.cs: définis une interfaceICommanddans l’espace de nomsTextEditoravec une seule méthodeExecute(). Crée ensuite deux classes de commandes concrètes :InsertCommand- prend unDocumentet une chaînetextdans son constructeur. Lors de son exécution, elle ajoute le texte au document et afficheInserted: {text}DeleteCommand- prend unDocumentet unint countdans son constructeur. Lors de son exécution, elle supprime lescountderniers caractères du document et afficheDeleted: {count} characters
Document.cs: crée une classeDocumentdans le même espace de noms. Il s’agit de ton récepteur, c’est-à-dire l’objet qui effectue réellement les opérations sur le texte. Il doit contenir :- Un champ privé de type chaîne pour stocker le contenu (initialisé avec une chaîne vide)
- Une méthode
Append(string text)qui ajoute du texte au contenu - Une méthode
RemoveLast(int count)qui supprime lescountderniers caractères (si count dépasse la longueur du contenu, elle efface tout le contenu) - Une méthode
GetContent()qui renvoie le contenu actuel
Program.cs: crée une classeEditorqui joue le rôle d’invocateur. Elle doit disposer d’une méthodeSetCommand(ICommand command)et d’une méthodeExecuteCommand()qui exécute la commande actuelle. Dans ton code principal, illustre le modèle Command en traitant une série d’opérations d’édition.
Tu recevras les entrées suivantes :
- Le nombre de commandes à exécuter
- Pour chaque commande : le type de commande (
insertoudelete), suivi soit du texte à insérer, soit du nombre de caractères à supprimer
Après avoir exécuté toutes les commandes, affiche le contenu final du document sur une nouvelle ligne au format Content: {content}.
Par exemple, si les entrées sont :
4
insert
Hello
insert
World
delete
3
insert
!La sortie doit être :
Inserted: Hello
Inserted: World
Deleted: 3 characters
Inserted: !
Content: Hello Wo!Remarque que l’Editor (l’invocateur) ne sait rien de la manipulation du texte : il exécute simplement la commande qui lui est fournie. Les commandes encapsulent à la fois l’action et le récepteur, ce qui facilite l’ajout de nouvelles opérations comme ReplaceCommand sans modifier l’éditeur !
Essayez vous-même
using System;
using TextEditor;
// TODO: Créer la classe Editor (l'invocateur)
public class Editor
{
// TODO: Ajouter un champ privé pour stocker la commande actuelle
private ICommand _command;
// TODO: Implémenter la méthode SetCommand
public void SetCommand(ICommand command)
{
// TODO: Stocker la commande
}
// TODO: Implémenter la méthode ExecuteCommand
public void ExecuteCommand()
{
// TODO: Exécuter la commande actuelle
}
}
class Program
{
public static void Main(string[] args)
{
// Lire le nombre de commandes
int n = Convert.ToInt32(Console.ReadLine());
// Créer le document (récepteur)
Document document = new Document();
// Créer l'éditeur (invocateur)
Editor editor = new Editor();
// TODO: Traiter chaque commande
for (int i = 0; i < n; i++)
{
string commandType = Console.ReadLine();
// TODO: En fonction de commandType, créer la commande appropriée
// - Si "insert" : lire le texte et créer InsertCommand
// - Si "delete" : lire le nombre et créer DeleteCommand
// Ensuite, définir la commande sur l'éditeur et l'exécuter
}
// TODO: Afficher le contenu final avec le format "Content: {content}"
}
}
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 externesEspaces de noms et directivesIntro aux classes et objetsLe mot-clé 'this'Méthodes et paramètresChamps vs PropriétésConstructeursInitialiseurs d'objetsRécapitulatif - Calculatrice simple4Héritage
Syntaxe de base de l'héritage (:)Le mot-clé 'base'Mots-clés Virtual & OverrideClasses scelléesLa classe de base 'object'Récapitulatif - Hiérarchie des employés7Fonctionnalités avancées
Surcharge d'opérateursIndexeurs (this[])Redéfinition de ToString()Méthodes d'extensionRécapitulatif - Liste personnalisée10Patrons de conception - Partie 1
Introduction aux patrons de conceptionSingleton Thread-SafePatron FabriquePatron Observateur (Événements)Patron Stratégie2Propriétés et membres statiques
Propriétés auto-implémentéesPropriétés en lecture/écriture seuleChamps et méthodes statiquesClasses statiquesMembres à corps d'expression5Polymorphisme & Interfaces
Polymorphisme : Compilation vs ExécutionInterface vs Classe AbstraiteInterfaces MultiplesInterfaces ExplicitesUpcasting & DowncastingRécapitulatif - Calculateur de Formes8Concepts avancés de la POO
Composition plutôt qu'héritageGénériques (Classes et Méthodes)Délégués et ÉvénementsAttributs et RéflexionIDisposable et l'instruction usingBases de l'Injection de Dépendances11Patrons de conception, Partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Méthode TemplatePatron ÉtatPatron Composite3Architecture des classes
Données d'instance vs statiquesMots-clés 'readonly' & 'const'Champs de supportRécapitulatif - Gestionnaire de compte bancaire6Encapsulation
Modificateurs d'accèsPropriétés pour l'encapsulationImplémentation du masquage de donnéesPatterns d'immuabilitéRécapitulatif - Dossiers d'étudiants12Projet : Système de gestion de bibliothèque
Structure du projetModèles Livre et UtilisateurLogique du système d'empruntLINQ pour la rechercheInterface Console / Interface d'administrationTests unitaires (NUnit/xUnit)Entraînez-vous par vous-même : Compilateur C# en ligne