Pattern Intent of Command?

1

In Elements of Reusable Object Oriented software di Erich Gamma, l'intento del modello di comando Command dice:

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

Che cosa significa l'autore di undoable operations ? Difficile capire cosa in realtà vuole fare riferimento qui. Gradirei un chiarimento.

    
posta Navjot Waraich 11.12.2018 - 02:24
fonte

3 risposte

9

What does the author mean by undoable operations? Hard to make out what he actually wants to refer here. I would appreciate a clarification.

Significa le operazioni che possono essere annullate (invertite in senso Ctrl-Z di una parola).

Al minimo un'interfaccia di comando astratta definisce il metodo Execute() . Se andiamo oltre il minimo, l'interfaccia di comando può anche definire un metodo Undo() . Se un Execute() aggiunge aritmeticamente un numero al suo ricevitore, ad esempio Undo() sottrae lo stesso numero dal totale, ad esempio.

L'invocatore può mantenere una lista dei comandi eseguiti in passato, invece di scartare ogni comando non appena eseguito. L'invocatore può chiamare Undo() sui comandi precedenti.

Buona discussione qui .

Gli esempi nel libro GoF non hanno i metodi Undo() .

    
risposta data 11.12.2018 - 03:17
fonte
2

Penso che sia difficile capire il modello senza guardare il codice. Che ne dici di comandare a un essere umano di camminare su una pista da passeggio?

Ecco un'implementazione di un modello di comando:

class Walk
{
    Walk(WalkingTrack track);

    Location walk(Human human);
}

Questo è semplicemente un Lambda Function per le lingue senza funzioni lambda.

Ecco un'altra implementazione del comando patttern:

class Walk
{
    Walk(WalkingTrack track);

    Walking walk(Human human);
}
class Walking
{
    Location location();
    bool completed();
    void cancel();
}

Questo è un comando cancellabile. È per sua natura asincrona e il chiamante (o chiunque abbia accesso all'oggetto Walking restituito) può richiedere l'interruzione del processo, o comunque monitorarne lo stato e forse il suo avanzamento.

Una versione annullabile del comando precedente richiederebbe che la chiamata cancel() annulli anche eventuali effetti collaterali introdotti dal Walking che elabora il comando. Essenzialmente rendendo la classe Walking una forma di Transazione.

Ecco un altro comando cancellabile:

class Walk
{
    Walk(WalkingTrack track);

    Location location();

    bool walk(Human human);
    bool walking();
    bool completed();
    void cancel();
}

Cerca di evitare questo layout. Combina diversi livelli di preoccupazione che ne offusca lo scopo. Rende anche più facile l'accettazione degli errori di utilizzo da parte del compilatore.

    
risposta data 11.12.2018 - 03:15
fonte
1

What does the author mean by undoable operations? Hard to make out what he actually wants to refer here. I would appreciate a clarification.

Significa solo il rollback delle modifiche. Suppongo che tu comprenda gli undos / redos e come funzionano per gli utenti solo in virtù dell'uso del software in generale (es: ctrl-Z per annullare un errore che hai fatto). Potrei sbagliarmi, ma ho interpretato la domanda come più su come il modello di comando facilita l'annullamento.

Con lo schema di comando hai questo oggetto e questa astrazione tra l'invocatore che vuole "fare qualcosa" e il ricevente che lo fa direttamente. Come esempio di base potresti avere un software di immagini in cui l'utente vuole sfocare un'immagine.

Con lo schema di comando avresti questo tipo di oggetto comando "Blur Image" con un'interfaccia astratta che tutti i comandi hanno in comune, e quindi hai questo oggetto comando da eseguire tra il codice che vuole sfocare un'immagine e il codice che effettivamente lo fa. E questo fornisce un respiratore nel mezzo di questi due per centralizzare le funzionalità come la registrazione di tutti i comandi che vengono eseguiti.

E allo stesso modo se l'interfaccia di comando astratta fornisce metodi come undo/redo , allora sottotipi di comando specifici possono implementare / sovrascrivere quelle funzioni per annullare e ripetere qualsiasi modifica apportata nell'esecuzione. Quindi, invece di scartare l'oggetto comando, il sistema può inviarlo alla cronologia ("Annulla pila") e iniziare a richiamare quei metodi di annullamento / ripetizione mentre l'utente si sposta nella cronologia, ad es.

A parte questo, non devi in effetti avere funzioni di undo/redo nell'interfaccia di comando per ottenere la funzionalità di annullamento / ripetizione in modi che ancora traggono vantaggio dallo schema di comando (volevo inserire principalmente per menzionare questo punto) . Anche in questo caso è presente un'area di esecuzione del comando centrale tra invoker e ricevitore, quindi in alternativa è possibile acquisire lo stato dell'applicazione prima dell'esecuzione di qualsiasi comando (che altererebbe tale stato) e inviare i dati (stato del programma) allo stack di annullamento (magari in un file compresso form) prima dell'esecuzione di qualsiasi comando e ciò facilita anche l'annullamento / ripetizione anche se i comandi stessi non forniscono la funzionalità undo/redo .

Hai questo tipo di "sandwich". Se l'invocatore e il ricevente sono come due pezzi di pane, lo schema di comando ti dà spazio per mettere tutti i tipi di cose nel mezzo della richiesta di eseguire alcune operazioni, come la registrazione centralizzata, in seguito potresti voler eseguire in modo uniforme i comandi in un asincrono posticipato se si desidera acquisire lo stato del programma prima dell'esecuzione di qualsiasi comando per l'annullamento, è possibile eseguire il comando in un processo separato in modo che se si blocca, l'applicazione host non si arresta in modo anomalo, ecc. ecc. se l'invocatore invoca direttamente funzioni nel ricevitore (es: sfocando le immagini direttamente senza alcun comando nel mezzo), non hai quel respiro centrale centralizzato per aggiungere e fare in modo uniforme quello che vuoi.

E in particolare in virtù del fatto che i comandi sono oggetti astratti che incapsulano i loro parametri di esecuzione, puoi tenerli in giro ed eseguirli in un secondo momento, eseguirli di nuovo, ecc., molto tempo dopo che il ricevitore ha fatto la richiesta originale. Puoi anche serializzarli a basso costo. Se lo stato del programma viene modificato in modo uniforme dai comandi, allora tale stato può estendersi su gigabyte ma la cronologia dei comandi di tutto l'utente potrebbe essere archiviata in kilobyte, e puoi rivalutare quei comandi e tornare esattamente nello stesso stato in cui si trovava l'utente semplicemente eseguendo di nuovo quegli stessi comandi con gli stessi parametri e ordinando l'utente inizialmente li ha invocati.

    
risposta data 11.12.2018 - 08:58
fonte