Untitled
unknown
plain_text
2 years ago
5.6 kB
9
Indexable
// Абстрактная команда задаёт общий интерфейс для конкретных
// классов команд и содержит базовое поведение отмены операции.
abstract class Command is
protected field app: Application
protected field editor: Editor
protected field backup: text
constructor Command(app: Application, editor: Editor) is
this.app = app
this.editor = editor
// Сохраняем состояние редактора.
method saveBackup() is
backup = editor.text
// Восстанавливаем состояние редактора.
method undo() is
editor.text = backup
// Главный метод команды остаётся абстрактным, чтобы каждая
// конкретная команда определила его по-своему. Метод должен
// возвратить true или false в зависимости о того, изменила
// ли команда состояние редактора, а значит, нужно ли её
// сохранить в истории.
abstract method execute()
// Конкретные команды.
class CopyCommand extends Command is
// Команда копирования не записывается в историю, так как
// она не меняет состояние редактора.
method execute() is
app.clipboard = editor.getSelection()
return false
class CutCommand extends Command is
// Команды, меняющие состояние редактора, сохраняют
// состояние редактора перед своим действием и сигнализируют
// об изменении, возвращая true.
method execute() is
saveBackup()
app.clipboard = editor.getSelection()
editor.deleteSelection()
return true
class PasteCommand extends Command is
method execute() is
saveBackup()
editor.replaceSelection(app.clipboard)
return true
// Отмена — это тоже команда.
class UndoCommand extends Command is
method execute() is
app.undo()
return false
// Глобальная история команд — это стек.
class CommandHistory is
private field history: array of Command
// Последний зашедший...
method push(c: Command) is
// Добавить команду в конец массива-истории.
// ...выходит первым.
method pop():Command is
// Достать последнюю команду из массива-истории.
// Класс редактора содержит непосредственные операции над
// текстом. Он отыгрывает роль получателя — команды делегируют
// ему свои действия.
class Editor is
field text: string
method getSelection() is
// Вернуть выбранный текст.
method deleteSelection() is
// Удалить выбранный текст.
method replaceSelection(text) is
// Вставить текст из буфера обмена в текущей позиции.
// Класс приложения настраивает объекты для совместной работы.
// Он выступает в роли отправителя — создаёт команды, чтобы
// выполнить какие-то действия.
class Application is
field clipboard: string
field editors: array of Editors
field activeEditor: Editor
field history: CommandHistory
// Код, привязывающий команды к элементам интерфейса, может
// выглядеть примерно так.
method createUI() is
// ...
copy = function() {executeCommand(
new CopyCommand(this, activeEditor)) }
copyButton.setCommand(copy)
shortcuts.onKeyPress("Ctrl+C", copy)
cut = function() { executeCommand(
new CutCommand(this, activeEditor)) }
cutButton.setCommand(cut)
shortcuts.onKeyPress("Ctrl+X", cut)
paste = function() { executeCommand(
new PasteCommand(this, activeEditor)) }
pasteButton.setCommand(paste)
shortcuts.onKeyPress("Ctrl+V", paste)
undo = function() { executeCommand(
new UndoCommand(this, activeEditor)) }
undoButton.setCommand(undo)
shortcuts.onKeyPress("Ctrl+Z", undo)
// Запускаем команду и проверяем, надо ли добавить её в
// историю.
method executeCommand(command) is
if (command.execute())
history.push(command)
// Берём последнюю команду из истории и заставляем её все
// отменить. Мы не знаем конкретный тип команды, но это и не
// важно, так как каждая команда знает, как отменить своё
// действие.
method undo() is
command = history.pop()
if (command != null)
command.undo()Editor is loading...
Leave a Comment