Паттерн Команда превращает запрос в объект, содержащий действие и его параметры. Такой объект можно хранить, передавать, ставить в очередь, логировать и, если он умеет себя отменять, откатывать. Это стандартный способ построить отмену/повтор в редакторах.

`History` запускает команды, работающие с `Document`
History запускает команды, работающие с Document

Роли

  • Команда объявляет execute() (и undo()).
  • Получатель (Document) выполняет настоящую работу.
  • Инициатор (History, кнопка) запускает команды и не знает, что они делают.

Команды с отменой

Insert и Delete хранят документ и свои параметры. undo() должен точно обратить то, что сделал execute(), поэтому команда сохраняет нужное в момент выполнения: Delete кладёт удалённый текст в self.removed.

python
class Document:
    def __init__(self):
        self.text = ""

class Insert:
    def __init__(self, doc, s):
        self.doc, self.s = doc, s

    def execute(self):
        self.doc.text += self.s

    def undo(self):
        n = len(self.doc.text) - len(self.s)
        self.doc.text = self.doc.text[:n]

class Delete:
    def __init__(self, doc, n):
        self.doc, self.n, self.removed = doc, n, ""

    def execute(self):
        cut = max(len(self.doc.text) - self.n, 0)
        self.removed = self.doc.text[cut:]
        self.doc.text = self.doc.text[:cut]