Patron Commande
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy. Leçon 70 sur 87.
Le patron Command est un patron de conception comportemental qui transforme une requête en un objet autonome contenant toutes les informations relatives à cette requête. Cette transformation vous permet de transmettre des requêtes comme 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.
Imaginez cela comme un restaurant : au lieu de dire directement au chef quoi cuisiner, vous écrivez votre commande sur un bon. Le serveur (invocateur) apporte le bon (commande) en cuisine, où elle peut être mise en file d’attente, priorisée ou même annulée. Ce modèle découple l’objet qui invoque l’opération de celui qui l’exécute.
Le modèle comporte quatre composants clés : une interface Command déclarant la méthode execute, des classes ConcreteCommand qui implémentent des actions spécifiques, un Receiver qui effectue le travail réel, et un Invoker qui déclenche les commandes :
interface Command {
void execute();
}class Light { // Récepteur
public void turnOn() {
System.out.println("Light is ON");
}
public void turnOff() {
System.out.println("Light is OFF");
}
}class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.turnOn();
}
}class RemoteControl { // Invocateur
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
}L’invocateur ne sait pas quelle action sera effectuée. Il appelle simplement execute() :
Light light = new Light();
Command lightOn = new LightOnCommand(light);
RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton(); // Sortie : Light is ONLe modèle Command se révèle particulièrement utile lorsque vous devez mettre des opérations en file d’attente, implémenter une fonctionnalité d’annulation/rétablissement ou planifier des tâches 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 domotique intelligent à l’aide du modèle Command ! Vous allez créer un système dans lequel différents appareils domestiques peuvent être contrôlés via des commandes, ce qui permet de mettre des actions en file d’attente, de les exécuter et même de les stocker pour une utilisation ultérieure, comme une télécommande universelle qui n’a pas besoin de savoir comment fonctionne chaque appareil en interne.
Vous organiserez votre code sur quatre fichiers :
Command.java: définissez l’interfaceCommandque toutes les commandes d’appareils implémenteront. Elle doit déclarer une seule méthodeexecute()qui effectue l’action de la commande.Devices.java: créez deux classes réceptrices représentant des appareils domestiques intelligents :Television- possède les méthodespowerOn()qui afficheTV is now ON,powerOff()qui afficheTV is now OFF, etsetChannel(int channel)qui afficheTV channel set to [channel].Thermostat- possède les méthodessetTemperature(int temp)qui afficheThermostat set to [temp] degreesetturnOff()qui afficheThermostat turned OFF.Commands.java: créez des classes de commandes concrètes qui encapsulent les opérations des appareils :TVOnCommand- reçoit unTelevisiondans son constructeur et appellepowerOn()lors de son exécution.TVOffCommand- reçoit unTelevisiondans son constructeur et appellepowerOff()lors de son exécution.TVChannelCommand- reçoit unTelevisionet unint channeldans son constructeur, puis appellesetChannel()avec ce canal lors de son exécution.ThermostatSetCommand- reçoit unThermostatet unint temperaturedans son constructeur, puis appellesetTemperature()avec cette valeur lors de son exécution.Main.java: créez une classeRemoteControl(l’invocateur) qui possède une méthodesetCommand(Command cmd)pour stocker une commande et une méthodepressButton()pour exécuter la commande stockée.Dans votre méthode principale, vous recevrez deux entrées : un numéro de chaîne TV (entier) et une température de thermostat (entier).
Créez un
Televisionet unThermostat. Créez unRemoteControlet illustrez le modèle Command en :- définissant un
TVOnCommandet en appuyant sur le bouton - définissant un
TVChannelCommandavec votre chaîne saisie et en appuyant sur le bouton - définissant un
ThermostatSetCommandavec votre température saisie et en appuyant sur le bouton - définissant un
TVOffCommandet en appuyant sur le bouton
- définissant un
Vous recevrez deux entrées dans l’ordre : la chaîne TV (entier), puis la température du thermostat (entier).
Par exemple, avec les entrées 5 et 72, votre sortie serait :
TV is now ON
TV channel set to 5
Thermostat set to 72 degrees
TV is now OFFRemarquez que le RemoteControl n’interagit jamais directement avec les appareils. Il ne connaît que l’interface Command. Chaque commande encapsule tout ce qui est nécessaire pour effectuer son action, ce qui facilite l’ajout de nouveaux appareils et de nouvelles commandes sans modifier l’invocateur !
Essayez vous-même
import java.util.Scanner;
// TODO: Créer la classe RemoteControl (l'invocateur) avec :
// - méthode setCommand(Command cmd) pour stocker une commande
// - méthode pressButton() pour exécuter la commande stockée
class RemoteControl {
// TODO: Implémenter RemoteControl
}
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Lire les entrées
int channel = scanner.nextInt();
int temperature = scanner.nextInt();
// TODO: Créer un Television et un Thermostat
// TODO: Créer un RemoteControl
// TODO: Démontrer le pattern Command :
// 1. Définir un TVOnCommand et appuyer sur le bouton
// 2. Définir un TVChannelCommand avec le canal d'entrée et appuyer sur le bouton
// 3. Set a ThermostatSetCommand with the input temperature and press the button
// 4. Définir un TVOffCommand et appuyer sur le bouton
scanner.close();
}
}
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 vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron ItérateurEntraînez-vous par vous-même : Compilateur Java en ligne