Menu
Coddy logo textTech

Pattern Command

Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 70 di 87.

Il Command Pattern è un pattern di progettazione comportamentale che trasforma una richiesta in un oggetto autonomo contenente tutte le informazioni sulla richiesta. Questa trasformazione ti permette di passare le richieste come argomenti dei metodi, ritardare o mettere in coda l'esecuzione di una richiesta e supportare operazioni annullabili.

Pensala come un ristorante: invece di dire direttamente allo chef cosa cucinare, scrivi il tuo ordine su un foglietto. Il cameriere (invocatore) porta il foglietto (comando) in cucina, dove può essere messo in coda, avere la priorità o persino essere annullato. Il pattern disaccoppia l’oggetto che invoca l’operazione da quello che la esegue.

Il pattern ha quattro componenti chiave: un’interfaccia Command che dichiara il metodo execute, classi ConcreteCommand che implementano azioni specifiche, un Receiver che esegue il lavoro effettivo e un Invoker che attiva i comandi:

interface Command {
    void execute();
}
class Light {  // Ricevitore
    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 {  // Invoker
    private Command command;
    
    public void setCommand(Command command) {
        this.command = command;
    }
    
    public void pressButton() {
        command.execute();
    }
}

L'invocatore non sa quale azione verrà eseguita. Si limita a chiamare execute():

Light light = new Light();
Command lightOn = new LightOnCommand(light);

RemoteControl remote = new RemoteControl();
remote.setCommand(lightOn);
remote.pressButton();  // Output: la luce è accesa

Il pattern Command eccelle quando devi mettere in coda delle operazioni, implementare la funzionalità di annullamento/ripristino o pianificare attività da eseguire in un secondo momento. Ogni comando incapsula tutto ciò che serve per eseguire un'azione, rendendo il tuo sistema più flessibile ed estensibile.

challenge icon

Sfida

Facile

Costruiamo un sistema di domotica intelligente usando il Pattern Command! Creerai un sistema in cui vari dispositivi domestici possono essere controllati tramite comandi, consentendo di accodare ed eseguire azioni e persino di memorizzarle per un uso successivo, proprio come un telecomando universale che non deve sapere come funziona internamente ciascun dispositivo.

Organizzerai il codice in quattro file:

  • Command.java: Definisci l'interfaccia Command che tutti i comandi dei dispositivi implementeranno. Deve dichiarare un unico metodo execute() che esegue l'azione del comando.
  • Devices.java: Crea due classi ricevitore che rappresentano i dispositivi domestici intelligenti:

    Television - ha i metodi powerOn() che stampa TV is now ON, powerOff() che stampa TV is now OFF e setChannel(int channel) che stampa TV channel set to [channel].

    Thermostat - ha i metodi setTemperature(int temp) che stampa Thermostat set to [temp] degrees e turnOff() che stampa Thermostat turned OFF.

  • Commands.java: Crea classi concrete di comandi che incapsulano le operazioni dei dispositivi:

    TVOnCommand - riceve un Television nel costruttore e chiama powerOn() quando viene eseguito.

    TVOffCommand - riceve un Television nel costruttore e chiama powerOff() quando viene eseguito.

    TVChannelCommand - riceve un Television e un int channel nel costruttore e chiama setChannel() con quel canale quando viene eseguito.

    ThermostatSetCommand - riceve un Thermostat e un int temperature nel costruttore e chiama setTemperature() con quel valore quando viene eseguito.

  • Main.java: Crea una classe RemoteControl (l'invocatore) che ha un metodo setCommand(Command cmd) per memorizzare un comando e pressButton() per eseguire il comando memorizzato.

    Nel metodo principale, riceverai due input: il numero del canale TV (intero) e la temperatura del termostato (intero).

    Crea un Television e un Thermostat. Crea un RemoteControl e mostra il Pattern Command:

    1. Impostare un TVOnCommand e premere il pulsante
    2. Impostare un TVChannelCommand con il canale inserito e premere il pulsante
    3. Impostare un ThermostatSetCommand con la temperatura inserita e premere il pulsante
    4. Impostare un TVOffCommand e premere il pulsante

Riceverai due input nell'ordine seguente: il canale TV (intero) e la temperatura del termostato (intero).

Ad esempio, con gli input 5 e 72, il risultato sarà:

TV is now ON
TV channel set to 5
Thermostat set to 72 degrees
TV is now OFF

Nota che RemoteControl non interagisce mai direttamente con i dispositivi. Conosce solo l'interfaccia Command. Ogni comando incapsula tutto ciò che serve per eseguire la propria azione, rendendo facile aggiungere nuovi dispositivi e comandi senza modificare l'invocatore!

Provalo tu

import java.util.Scanner;

// TODO: Crea la classe RemoteControl (l'invocatore) con:
// - il metodo setCommand(Command cmd) per memorizzare un comando
// - il metodo pressButton() per eseguire il comando memorizzato

class RemoteControl {
    // TODO: Implementa RemoteControl
}

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leggi i valori di input
        int channel = scanner.nextInt();
        int temperature = scanner.nextInt();
        
        // TODO: Crea un Television e un Thermostat
        
        // TODO: Crea un RemoteControl
        
        // TODO: Illustra il Command Pattern:
        // 1. Imposta un TVOnCommand e premi il pulsante
        // 2. Imposta un TVChannelCommand con il canale di input e premi il pulsante
        // 3. Imposta un ThermostatSetCommand con la temperatura di input e premi il pulsante
        // 4. Imposta un TVOffCommand e premi il pulsante
        
        scanner.close();
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Java online