web-dev-qa-db-fra.com

structure de données utilisée pour implémenter l'option UNDO et REDO

Je veux implémenter l'option UNDO et REDO (comme nous le voyons dans MS Word, etc.). Pouvez-vous me suggérer une structure de données pour cela, et comment puis-je l'implémenter.?

45
SyncMaster

Ce n'est pas une structure de données mais un modèle de conception. Vous recherchez le Command Pattern .

La norme consiste à conserver les objets Command dans une pile pour prendre en charge l'annulation à plusieurs niveaux. Afin de prendre en charge le rétablissement, une deuxième pile conserve toutes les commandes que vous avez annulées. Ainsi, lorsque vous ouvrez la pile d'annulation pour annuler une commande, vous appuyez sur la même commande que vous avez insérée dans la pile de rétablissement. Vous faites la même chose en sens inverse lorsque vous refaites une commande. Vous ouvrez la pile de rétablissement et repoussez la commande sautée dans la pile d'annulation.

101
Jason Punyon

En fait, le modèle standard pour cette fonctionnalité (Gang of Four, pair) est Memento .

De plus, alors que la plupart des programmes utilisent les piles Annuler/Rétablir, les afficionados de certains éditeurs de texte préfèrent les arbres Annuler/Rétablir afin qu'ils ne perdent pas leur historique complet si ils annulent quelques commandes, en essaient une nouvelle et changent d'avis.

35
Hank Gay

Objective-C Cocoa a une réponse bien documentée nommée NSUndoManager .

2
mouviciel

Vous pouvez utiliser le modèle de commande pour réaliser Annuler/Rétablir

Vérifiez ces échantillons:

http://www.codeproject.com/csharp/undoredobuffer.asp

http://www.dofactory.com/Patterns/PatternCommand.aspx

1
NinethSense

Il s'agit d'un cas classique de modèle de commande. Voici un exemple d'implémentation de la fonction d'annulation dans 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',))
1
Red John