Middle+
Utilizzi il pattern Command nel tuo lavoro?
sobes.tech AI
Risposta dell'AI
Sì, utilizzo il pattern Command nel mio lavoro.
Il pattern Command (Comando) incapsula una richiesta sotto forma di oggetto, consentendo di parametrizzare i client con richieste diverse, metterle in coda o registrarle, e supportare l'annullamento delle operazioni.
Lo applico quando:
- È necessario parametrizzare gli oggetti con l'azione da eseguire.
- È necessario mettere le operazioni in coda, pianificarne l'esecuzione o registrarle.
- È necessario implementare un meccanismo di annullamento (undo) o ripetizione (redo) delle operazioni.
- Le operazioni a basso livello devono essere adattate per componenti di livello superiore.
Esempi di utilizzo:
- Sistemi con interfaccia grafica, dove i comandi corrispondono alle azioni dell'utente (ad esempio, "Incolla", "Copia").
- Sistemi di gestione delle transazioni.
- Sistemi distribuiti e code di messaggi.
- Implementazione di macro o script.
Strutturalmente, il pattern include:
Command: interfaccia o classe astratta che dichiara il metodo per eseguire l'operazione.ConcreteCommand: implementazione concreta diCommand, che collega il ricevitore all'azione. Contiene un riferimento aReceiver.Client: crea l'oggettoConcreteCommande imposta il ricevitore.Invoker: chiama l'esecuzione del comando. Tiene un oggettoCommand.Receiver: oggetto che esegue l'azione vera e propria.
Esempio: implementazione semplice di un comando per accendere/spegnere la luce.
// Interfaccia del comando
interface Command {
void execute();
void undo(); // Per supporto undo
}
// Ricevitore
class Light {
private boolean isOn = false;
public void turnOn() {
isOn = true;
System.out.println("Luce accesa");
}
public void turnOff() {
isOn = false;
System.out.println("Luce spenta");
}
}
// Comando concreto per accendere la luce
class TurnOnLightCommand implements Command {
private Light light;
public TurnOnLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOn();
}
@Override
public void undo() {
light.turnOff(); // Per annullare
}
}
// Comando concreto per spegnere la luce
class TurnOffLightCommand implements Command {
private Light light;
public TurnOffLightCommand(Light light) {
this.light = light;
}
@Override
public void execute() {
light.turnOff();
}
@Override
public void undo() {
light.turnOn(); // Per annullare
}
}
// Invocatore
class RemoteControl {
private Command command;
public void setCommand(Command command) {
this.command = command;
}
public void pressButton() {
command.execute();
}
public void pressUndoButton() {
command.undo(); // Per annullare
}
}
// Cliente
public class Client {
public static void main(String[] args) {
Light livingRoomLight = new Light(); // Ricevitore
Command turnOn = new TurnOnLightCommand(livingRoomLight); // Comando concreto
Command turnOff = new TurnOffLightCommand(livingRoomLight);
RemoteControl remote = new RemoteControl(); // Invocatore
remote.setCommand(turnOn);
remote.pressButton(); // Luce accesa
remote.pressUndoButton(); // Luce spenta
remote.setCommand(turnOff);
remote.pressButton(); // Luce spenta
remote.pressUndoButton(); // Luce accesa
}
}
Confronto con altri pattern:
| Pattern | Scopo principale | Differenza da Command |
|---|---|---|
| Strategy | Definire una famiglia di algoritmi e incapsularli. | Incapsula un intero algoritmo (cosa fare), mentre Command incapsula un'azione specifica (come farlo). |
| Observer | Definire una dipendenza "uno a molti" tra oggetti. | Riguarda le notifiche di cambiamenti di stato, non l'esecuzione di richieste. |
| Memento | Salvare e ripristinare lo stato di un oggetto senza violare l'incapsulamento. | Usato per salvare lo stato, non per incapsulare azioni. |