У3.9 Механизм истории
У3.7 Необратимые команды
У3.6 Составные команды
У3.5 Сохранение командных объектов
У3.4 Undo, Skip и Redo
У3.3 Undo-redo в Pascal
Объясните, как применить рассмотренную технику в не ОО-языках, подобных Pascal, Ada (используя записи с вариантами) или C (используя структуры и union типы). Сравните с ОО-решениями.
С учетом проблем, поднятых в обсуждении, рассмотрите, как можно расширить механизм, разработанный в этой лекции так, чтобы он допускал поддержку Undo, Skip и Redo, а также делал возможным повтор и откат, перемежаемый обычными командами. Обсудите эффект обоих новинок как на уровне интерфейса, так и реализации.
Рассмотрите аргументы команды независимо от команд и создайте только один командный объект на каждый тип команды.
Если вы выполнили предыдущее упражнение, примените эту технику к решению.
В некоторых системах может быть полезным ввести понятие составной команды, выполнение которых включает выполнение нескольких других команд. Напишите соответствующий класс COMPOSITE_COMMAND, потомка COMMAND, убедитесь, что составные команды допускают откат и что компонента составной команды может быть составной командой.
Система может включать необратимые команды либо по самой их природе ("Запуск ракет"), либо по прагматичным причинам больших расходов, связанных с отменой действия команды. Усовершенствуйте решение так, чтобы оно учитывало возможность присутствия необратимых команд. Внимательно изучите алгоритмы и интерфейс пользователя, в частности используйте окно истории.
Указание: введите наследников UNDOABLE и NON_UNDOABLE класса COMMAND.
У3.8 Библиотека команд (проектирование и реализация)
Напишите общецелевую библиотеку команд, предполагающую использование в произвольной интерактивной системе и поддерживающую неограниченный механизм undo-redo. Библиотека должна интегрировать свойства, обсуждаемые в последних трех упражнениях: отделение команд от их аргументов, составные команды, необратимые команды. Возможно также встраивание свойства "Undo, Skip и Redo". Проиллюстрируйте применимость библиотеки, построив на ее основе три демонстрационные системы различной природы, такие как текстовый редактор, графическая система, инструмент тестирования.
Полезным компонентом, встраиваемым в командно-ориентированный инструментарий, является механизм истории, запоминающий выполненную команду и позволяющий пользователю повторно ее выполнить, возможно, модифицировав. Под Unix, например, доступен командный язык C-shell, запоминающий несколько последних выполненных команд. Вы можете напечатать !-2, означающее, что нужно выполнить команду, предшествующую последней. Запись ^yes^no^ означает "выполнение последней команды с заменой yes на no". Другие окружения предлагают схожие свойства.
Механизмы истории, когда они существуют, построены в соответствии с модой. Под Unix многие интерактивные средства, выполняемые под C-shell, такие как текстовый редактор Vi или различные отладчики, будут получать преимущества от такого механизма, но он не будет предлагаться другим системам. Это тем более вызывает сожаление, что те же концепции истории команд и те же ассоциированные свойства полезны любой интерактивной системе независимо от выполняемых ею функций.
Спроектируйте класс, реализующий механизм истории общецелевого назначения, так чтобы любая интерактивная система, нуждающаяся в этом механизме, могла получить его путем простого наследования класса. (Заметьте, множественное наследование здесь необходимо.)
Обсудите расширение этого механизма на общий класс USER_INTERFACE.