На мою думку, УНДО / РЕДО можна було б реалізувати двома способами широко. 1. Рівень команди (називається командним рівнем Скасувати / Повторити) 2. Рівень документа (називається глобальним Скасувати / Повторити)
Командний рівень: Оскільки багато відповідей вказують, це ефективно досягається за допомогою шаблону Memento. Якщо команда також підтримує перенесення дій, повтор легко підтримується.
Обмеження: Після того, як область дії команди вимкнена, скасувати / повторити неможливо, що призводить до скасування / повтору на рівні документа (глобального)
Я думаю, що ваш випадок впишеться в глобальний скасування / повтор, оскільки він підходить для моделі, яка передбачає багато місця в пам'яті. Також це підходить, щоб також вибірково скасовувати / повторювати. Існує два примітивні типи
- Скасувати / повторити всю пам'ять
- Рядок об’єкта Скасувати Повторити
У "Скасувати / Повторити всю пам'ять" вся пам'ять розглядається як підключені дані (наприклад, дерево, список або графік), а пам'яттю керує програма, а не ОС. Тож нові та видалені оператори, якщо в C ++ перевантажені, щоб містити більш конкретні структури для ефективної реалізації операцій, таких як. Якщо будь-який вузол модифікований, b. зберігання та очищення даних і т.д., спосіб його функціонування - це, в основному, копіювання всієї пам'яті (якщо припустити, що розподіл пам’яті вже оптимізовано та управляється програмою за допомогою вдосконалених алгоритмів) та зберігати їх у стеку. Якщо вимагається копія пам'яті, структура дерева копіюється, виходячи з необхідності мати дрібну або глибоку копію. Глибока копія робиться лише для тієї змінної, яка модифікована. Оскільки кожна змінна розміщена за допомогою спеціального розподілу, додаток має остаточне слово, коли його потрібно буде видалити, якщо виникне необхідність. Речі стають дуже цікавими, якщо нам доведеться розділити Скасувати / Повторити, коли так трапляється, що нам потрібно програмно-вибірково Скасувати / Повторити набір операцій. У цьому випадку лише цим новим змінним, або видаленим змінним або модифікованим змінним надається прапор, щоб скасувати / скасувати лише скасувати / повторно виправити ці пам'яті. Речі стають ще цікавішими, якщо нам потрібно зробити часткове скасування / повторення всередині об'єкта. У такому випадку використовується новіша ідея "Шаблон відвідувачів". Він називається "Скасувати / повторити рівень об'єкта" або видаленим змінним або модифікованим змінним надається прапор, щоб скасувати / скасувати лише скасувати / повторити цю пам'ять. Все стає ще цікавішим, якщо нам потрібно зробити часткове скасування / повторення всередині об'єкта. У такому випадку використовується новіша ідея "Шаблон відвідувачів". Він називається "Скасувати / повторити рівень об'єкта" або видаленим змінним або модифікованим змінним надається прапор, щоб скасувати / скасувати лише скасувати / повторити цю пам'ять. Все стає ще цікавішим, якщо нам потрібно зробити часткове скасування / повторення всередині об'єкта. У такому випадку використовується новіша ідея "Шаблон відвідувачів". Він називається "Скасувати / повторити рівень об'єкта"
- Рівень об'єкта Скасувати / Повторити: Коли викликається повідомлення про скасування / повтор, кожен об'єкт реалізує операцію потокової передачі, в якій стример отримує від об'єкта старі дані / нові дані, які запрограмовані. Дані, які не турбують, залишаються непорушеними. Кожен об'єкт отримує стример як аргумент, і всередині виклику UNDo / Redo він передає / передає потоки даних об'єкта.
І 1, і 2 можуть мати такі методи, як 1. BeforeUndo () 2. AfterUndo () 3. BeforeRedo () 4. AfterRedo (). Ці методи повинні бути опубліковані в базовій команді "Скасувати / повторити" (а не в контекстній команді), щоб усі об'єкти також реалізували ці методи для отримання конкретних дій.
Хорошою стратегією є створення гібриду 1 і 2. Приємним є те, що ці методи (1 і 2) самі використовують командні схеми