Meiner Meinung nach könnte das UNDO / REDO auf zwei Arten allgemein umgesetzt werden. 1. Befehlsebene (als Befehlsebene bezeichnet Rückgängig / Wiederherstellen) 2. Dokumentebene (als globales Rückgängig / Wiederherstellen bezeichnet)
Befehlsebene: Wie viele Antworten zeigen, wird dies mithilfe des Memento-Musters effizient erreicht. Wenn der Befehl auch das Journalisieren der Aktion unterstützt, wird ein Wiederherstellen problemlos unterstützt.
Einschränkung: Sobald der Umfang des Befehls abgelaufen ist, ist das Rückgängigmachen / Wiederherstellen nicht mehr möglich, was zum (globalen) Rückgängigmachen / Wiederherstellen auf Dokumentebene führt
Ich denke, Ihr Fall würde in das globale Rückgängigmachen / Wiederherstellen passen, da er für ein Modell geeignet ist, das viel Speicherplatz benötigt. Dies ist auch geeignet, um auch selektiv rückgängig zu machen / zu wiederholen. Es gibt zwei primitive Typen
- Alle Speicher rückgängig machen / wiederholen
- Objektebene Wiederherstellen rückgängig machen
In "Alle Speicher rückgängig machen / wiederholen" wird der gesamte Speicher als verbundene Daten (z. B. ein Baum, eine Liste oder ein Diagramm) behandelt, und der Speicher wird von der Anwendung und nicht vom Betriebssystem verwaltet. Daher werden neue und gelöschte Operatoren in C ++ überladen, um spezifischere Strukturen zu enthalten, um Operationen wie a effektiv zu implementieren. Wenn ein Knoten geändert wird, b. Halten und Löschen von Daten usw. Die Funktionsweise besteht im Wesentlichen darin, den gesamten Speicher zu kopieren (vorausgesetzt, die Speicherzuordnung wird bereits von der Anwendung mithilfe fortschrittlicher Algorithmen optimiert und verwaltet) und in einem Stapel zu speichern. Wenn die Kopie des Speichers angefordert wird, wird die Baumstruktur basierend auf der Notwendigkeit einer flachen oder tiefen Kopie kopiert. Eine tiefe Kopie wird nur für die Variable erstellt, die geändert wird. Da jede Variable mithilfe einer benutzerdefinierten Zuordnung zugewiesen wird, Die Anwendung hat das letzte Wort, wann sie bei Bedarf gelöscht werden muss. Die Dinge werden sehr interessant, wenn wir das Rückgängigmachen / Wiederherstellen partitionieren müssen, wenn es passiert, dass wir eine Reihe von Operationen programmgesteuert und selektiv rückgängig machen / wiederholen müssen. In diesem Fall erhalten nur diese neuen Variablen oder gelöschten Variablen oder geänderten Variablen ein Flag, sodass Rückgängig / Wiederherstellen nur diesen Speicher rückgängig macht / wiederherstellt. Die Dinge werden noch interessanter, wenn wir ein teilweises Rückgängigmachen / Wiederherstellen innerhalb eines Objekts durchführen müssen. In diesem Fall wird eine neuere Idee des "Besuchermusters" verwendet. Es heißt "Object Level Undo / Redo" oder gelöschte Variablen oder geänderte Variablen erhalten ein Flag, so dass Rückgängig / Wiederherstellen nur diesen Speicher rückgängig macht / wiederherstellt. Die Dinge werden noch interessanter, wenn wir ein teilweises Rückgängigmachen / Wiederherstellen innerhalb eines Objekts durchführen müssen. In diesem Fall wird eine neuere Idee des "Besuchermusters" verwendet. Es heißt "Object Level Undo / Redo" oder gelöschte Variablen oder geänderte Variablen erhalten ein Flag, so dass Rückgängig / Wiederherstellen nur diesen Speicher rückgängig macht / wiederherstellt. Die Dinge werden noch interessanter, wenn wir ein teilweises Rückgängigmachen / Wiederherstellen innerhalb eines Objekts durchführen müssen. In diesem Fall wird eine neuere Idee des "Besuchermusters" verwendet. Es heißt "Object Level Undo / Redo"
- Objektebene Rückgängig / Wiederherstellen: Wenn die Benachrichtigung zum Rückgängigmachen / Wiederherstellen aufgerufen wird, implementiert jedes Objekt eine Streaming-Operation, bei der der Streamer vom Programm die alten Daten / neuen Daten erhält, die programmiert sind. Die Daten, die nicht gestört werden, bleiben ungestört. Jedes Objekt erhält einen Streamer als Argument und innerhalb des UNDo / Redo-Aufrufs werden die Daten des Objekts gestreamt / entströmt.
Sowohl 1 als auch 2 können Methoden wie 1. BeforeUndo () 2. AfterUndo () 3. BeforeRedo () 4. AfterRedo () haben. Diese Methoden müssen im grundlegenden Befehl "Rückgängig / Wiederherstellen" (nicht im Kontextbefehl) veröffentlicht werden, damit alle Objekte diese Methoden ebenfalls implementieren, um eine bestimmte Aktion zu erhalten.
Eine gute Strategie besteht darin, eine Mischung aus 1 und 2 zu erstellen. Das Schöne ist, dass diese Methoden (1 und 2) selbst Befehlsmuster verwenden