Sì, è assolutamente OK aggiungere parametri al metodo execute()
. È bene ricordare come e perché viene utilizzato lo schema di comando: come una sorta di funzione lambda. In Java 8, spesso non è più necessario implementare una classe di comando concreta, perché invece possiamo utilizzare lambdas o riferimenti al metodo, supponendo che ICommand
sia un @FunctionalInterface
.
Un oggetto comando può salvare un certo contesto nei campi di istanza e un lambda può catturare variabili che racchiudono, ma il metodo di esecuzione può ancora prendere parametri extra e persino restituire valori! Presta attenzione a definire l'interfaccia di comando in un modo che risolva i tuoi problemi. Ciò potrebbe anche significare che l'interfaccia Command richiede più metodi, nel qual caso non può più essere un'interfaccia funzionale.
Come esempio tradizionale per lo schema di comando. potremmo avere una GUI in cui l'utente fa clic su un pulsante. Diamo al pulsante un comando da eseguire. Il pulsante non fornisce dati e non può utilizzare alcun valore di ritorno, quindi potremmo definire
@FunctionalInterface
interface ButtonCommand {
void execute();
}
In uno scenario completamente diverso, potremmo avere un sistema di bilanciamento degli account guidato dagli eventi. Un comando riceverà lo stato del vecchio account e restituirà il nuovo stato dell'account. Quindi il nostro design potrebbe essere simile a:
@FunctionalInterface
interface AccountCommand {
int execute(int balance);
}
class SendCommand implements AccountCommand {
int amount;
public SendCommand(int amount) { this.amount = amount; }
@Override public int execute(int balance) { return balance - amount; }
}
class ReceiveCommand implements AccountCommand {
int amount;
public ReceiveCommand(int amount) { this.amount = amount; }
@Override public int execute(int balance) { return balance + amount; }
}
class Account {
int balance = 0;
public int getBalance() { return balance; }
public void executeCommand(AccountCommand command) {
balance = command.execute(balance);
}
}
public static void main(String[] argv) {
AccountCommand[] events = {
new ReceiveCommand(70),
// custom command for interest
balance -> (int)(balance * 1.02),
new SendCommand(30),
new SendCommand(20),
};
Account acc = new Account();
for (AccountCommand cmd : events) {
int oldBalance = acc.getBalance();
acc.executeCommand(cmd);
int newBalance = acc.getBalance();
System.out.println("Account balance changed from " + oldBalance + " to " + newBalance);
}
}
Potrebbe essere preferibile aggiungere ulteriori metadati a questi comandi (come la controparte della transazione o l'autorizzazione per questo comando). L'account potrebbe anche tenere un registro dei comandi applicati, annullare i comandi e così via. Quindi lo schema di comando può essere più flessibile di un semplice lambda.