Сохранение последней команды
Располагая понятием объекта command, можно добавить специфику в выполняемые операции, введя атрибуты:
requested: COMMAND --Команда, запрашиваемая пользователемАтрибут задает последнюю команду, подлежащую выполнению, отмене или повтору. Это позволяет уточнить нашу схему следующим образом:
"Получить и декодировать последний запрос пользователя" if "Запрос является нормальной командой (не Undo)" then "Создать подходящий объект command и присоединить его к requested" -- requested создан как экземпляр некоторого потомка -- класса COMMAND, такого как LINE_DELETION. -- (Эта инструкция детализируется ниже.) else requested.execute; undoing_mode := False elseif "Запрос является Undo" and requested /= Void then if undoing_mode then "Это Redo; детали оставляем читателям" else requested.undo; undoing_mode := True end else "Ошибочный запрос: вывод предупреждения или игнорирование" end
Булева сущность undoing_mode определяет, была ли Undo последней операцией. В этом случае непосредственно следующий запрос Undo будет означать Redo, хотя непосредственные детали остаются за читателем, (упражнение У3.2); мы увидим полную реализацию Redo в более интересном случае многоуровневого механизма. |
Информация, сохраняемая перед каждым выполнением команды, задается в экземпляре некоторого потомка COMMAND, такого как LINE_DELETION. Это означает, что, как и анонсировалось, решение удовлетворяет свойству U3 в списке требований: хранится не все состояние, а только разница между новым состоянием и предыдущим.
Ключом решения - и его уточнением в оставшейся части лекции - является полиморфизм и динамическое связывание. Атрибут requested полиморфен: объявленный как COMMAND он присоединяется к объектам одного из эффективных потомков, таким как LINE_INSERTION. Вызовы requested.execute и requested.undo осмыслены из-за динамического связывания: подключаемый компонент должен быть версией, определенной в соответствующем классе, выполняя, например, откат LINE_INSERTION, LINE_DELETION или команду любого другого типа, определенного тем объектом, к которому присоединен requested во время вызова.