2009-03-31 10 views

risposta

92

Non è una struttura dati ma un modello di progettazione. Stai cercando il Command Pattern.

Lo standard è di mantenere gli oggetti Command in una pila per supportare l'annullamento a più livelli. Per supportare il ripristino, un secondo stack mantiene tutti i comandi che hai annullato. Quindi, quando si apre lo stack di annullamento per annullare un comando, si preme lo stesso comando che è stato eseguito nella pila di ripetizione. Fai la stessa cosa al contrario quando rifai un comando. Si apre lo stack di ripetizione e si reinserisce il comando popped nello stack di annullamento.

+28

Inoltre, è importante cancellare sempre lo stack di ripetizione se si preme un altro comando. – Balk

+10

La struttura dati è Stack con istanze di oggetti "Comando". – zinovii

+1

Mi sembra che lo schema di comando non sia necessariamente il modo in cui si implementa l'annullamento, è solo un'opzione, né la risposta alla domanda dell'OP. Le pile di annullamento/ripetizione è la risposta. (Anche se suppongo abbia menzionato MSWord.) –

31

In realtà, il modello standard per questa funzionalità (Gang of Four, anche) è Memento.

Inoltre, mentre la maggior parte dei programmi utilizzano Undo/Redo pile, estimatori di alcuni editor di testo preferiscono Undo/Redo alberi in modo che essi non perdono tutta la loro storia se annullare alcuni comandi, provare una nuova e cambiare idea.

+3

Hai ragione. Se aggiungi ulteriori informazioni su come interagisce con lo schema di comando, questa sarebbe un'ottima risposta. – Kieveli

+0

Provare a cancellare l'uso di Memento, Is Memento utilizzato per memorizzare lo stato degli oggetti prima e dopo l'operazione per undoo/redo? – NileshChauhan

+1

L'oggetto che produce il Memento lo utilizza per tornare a quello stato. Il Memento stesso dovrebbe essere trattato come se fosse opaco. Riempire l'intero stato nel Memento sembra una scelta di implementazione ovvia, ma potrebbe facilmente essere un diff o un id in un backing store o qualcos'altro. –

0

Questo è un caso classico di Command Pattern. Di seguito è riportata un'implementazione di esempio della funzionalità di annullamento in Python:

from os import rename 
class RenameFileCommand(object): 
    def __init__(self, src_file, target_file): 
     self.src_file=src_file 
     self.target_file=target_file 


    def execute(self): 
     rename(self.src_file, self.target_file) 

    def undo(self): 
     rename(self.target_file,self.src_file) 



class History(object): 
    def __init__(self): 
     self.commands=list() 
    def execute(self, command): 
     command.execute() 
     self.commands.append(command) 

    def undo(self): 
     self.commands.pop().undo() 


if __name__=='__main__': 
    hist=History() 
    hist.execute(RenameFileCommand('test1.txt', 'tmp.txt',)) 
    hist.undo() 
    hist.execute(RenameFileCommand('tmp2.txt', 'test2.txt',)) 
Problemi correlati