Command: make an action a value
Picture
“Append hello” can remember both the target document and the requested text instead of running immediately.
Predict
Can every external action be undone merely because it is a command?
Walk through the small example
No, undo needs real inverse behavior. Sending an email or shipping a parcel cannot simply be erased by an undo method.
Mental model and complete Python solution
A command captures the receiver and operation parameters. AppendCommand saves a before and after value and permits one execute followed by an undo only when the document still equals its expected after value. A practical editor would coordinate a command history and clear or rebase it on conflicting edits. Commands can support queues, audit, and undo, but those guarantees require explicit supporting state.
What the function promises: A command permits one active execution; successful undo allows execution again. Undo refuses when the document differs from the expected result. Equal text does not prove no intervening edits occurred; a real editor should track revisions. The example is local and single-threaded.
class Document:
def __init__(self, text=""):
self.text = text
class AppendCommand:
def __init__(self, document, text):
self.document, self.text = document, text
self.executed = False
def execute(self):
if self.executed:
raise ValueError("Command already executed")
self.before = self.document.text
self.after = self.before + self.text
self.document.text = self.after
self.executed = True
def undo(self):
if not self.executed or self.document.text != self.after:
raise ValueError("Cannot safely undo this command")
self.document.text = self.before
self.executed = False
doc = Document("Hi")
command = AppendCommand(doc, "!")
command.execute()
assert doc.text == "Hi!"
command.undo()
assert doc.text == "Hi"
Work and storage: O(text length) copied string work and snapshot storage.
When to recognize it: Remember the previous text. Undo is safe only if no later unrelated edit has changed the document since this command ran.
Check before applying it: Not every command has a true inverse. Define retry and undo behavior before advertising them.
Change one rule
An operation spans payment and shipping services. Is undo the same as database rollback?
See what changes
No. A compensating action such as refunding is a new business operation, may fail, and may not erase history. That distinction leads to sagas.
Connect
Tell interested objects what happened: An event announces what happened; a command asks for an action.
Memento: preserve a restorable snapshot: Undo can preserve previous state through a memento.