По моему мнению, UNDO / REDO может быть реализовано двумя способами в широком смысле.
1. Командный уровень (называется командный уровень Undo / Redo)
2. Уровень документа (называемый глобальным Undo / Redo)
Уровень команд: как указывают многие ответы, это эффективно достигается с помощью шаблона Memento. Если команда также поддерживает журналирование действия, повторное выполнение легко поддерживается.
Ограничение: Как только область действия команды вышла, отмена / повтор невозможна, что приводит к уровню документа (глобальному) отмена / повтор
Полагаю, ваш случай вписался бы в глобальную отмену / повтор, поскольку он подходит для модели, которая занимает много места в памяти. Кроме того, это подходит для выборочного отмены / повтора также. Есть два примитивных типа
- Отмена всей памяти / повтор
- Уровень объекта Отменить Повторить
В «Отмена / восстановление всей памяти» вся память обрабатывается как связанные данные (например, дерево, или список, или график), а память управляется приложением, а не ОС. Поэтому операторы new и delete в C ++ перегружены, чтобы содержать более конкретные структуры для эффективной реализации таких операций, как a. Если какой-либо узел изменен, б. хранение и очистка данных и т. д.,
Он работает в основном для копирования всей памяти (при условии, что распределение памяти уже оптимизировано и управляется приложением с использованием расширенных алгоритмов) и сохранения его в стеке. Если запрашивается копия памяти, древовидная структура копируется на основе необходимости иметь неглубокую или глубокую копию. Глубокая копия сделана только для той переменной, которая изменена. Поскольку каждая переменная выделяется с помощью пользовательского выделения, приложение имеет последнее слово, когда нужно удалить ее, если это необходимо.
Вещи становятся очень интересными, если мы должны разделить Undo / Redo, когда это происходит, когда нам нужно программно-выборочно Undo / Redo набор операций. В этом случае только этим новым переменным, или удаленным переменным, или измененным переменным присваивается флаг, так что Undo / Redo только отменяет / восстанавливает эту память
Вещи становятся еще более интересными, если нам нужно сделать частичную отмену / возврат внутри объекта. Когда это так, используется более новая идея «Шаблон посетителя». Он называется «Отменить / повторить уровень объекта»
- Уровень объекта Отменить / Повторить: Когда вызывается уведомление об отмене / повторе, каждый объект реализует потоковую операцию, в которой стример получает от объекта старые данные / новые данные, которые запрограммированы. Данные, которые не подлежат нарушению, остаются без изменений. Каждый объект получает в качестве аргумента стример, и внутри вызова UNDo / Redo он направляет / выводит данные объекта.
И 1, и 2 могут иметь такие методы, как
1. BeforeUndo ()
2. AfterUndo ()
3. BeforeRedo ()
4. AfterRedo (). Эти методы должны быть опубликованы в базовой команде Undo / redo (не в контекстной команде), чтобы все объекты реализовали эти методы, чтобы получить определенное действие.
Хорошая стратегия - создать гибрид из 1 и 2. Прелесть в том, что эти методы (1 и 2) сами используют шаблоны команд