web-dev-qa-db-ja.com

UNDOおよびREDOオプションの実装に使用されるデータ構造

UNDOおよびREDOオプションを実装したい(MS Wordなどで見られるように)。そのデータ構造を提案してもらえますか?どのように実装できますか?

45
SyncMaster

データ構造ではなく、設計パターンです。 コマンドパターン を探しています。

標準は、コマンドオブジェクトをスタックに保持して、マルチレベルの取り消しをサポートすることです。やり直しをサポートするために、2番目のスタックは、取り消したすべてのコマンドを保持します。したがって、取り消しスタックをポップしてコマンドを取り消すと、ポップしたコマンドをやり直しスタックにプッシュします。コマンドをやり直すときに、同じことを逆に行います。 REDOスタックをポップし、ポップしたコマンドを元に戻すスタックにプッシュします。

101
Jason Punyon

実際、この機能の標準パターン(Gang of Fourなど)は Memento です。

また、ほとんどのプログラムは元に戻す/やり直しスタックを使用しますが、特定のテキストエディターの愛好家は、元に戻す/やり直しツリーを好むため、履歴全体が失われることはありません。彼らはいくつかのコマンドを元に戻し、新しいコマンドを試し、考えを変えます。

35
Hank Gay

Objective-C Cocoaには NSUndoManager という名前のよく文書化されたanwserがあります。

2
mouviciel

コマンドパターンを使用して、元に戻す/やり直すことができます。

これらのサンプルを確認してください:

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

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

1
NinethSense

これはコマンドパターンの典型的なケースです。以下は、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