🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Command Pattern Implementor

by @quochungto

Implement the Command pattern to encapsulate requests as objects, enabling parameterized operations, queuing, logging, and undo/redo. Use when you need to de...

Versionv1.0.0
⚑ When to Use
TriggerAction
- UI elements (menu items, toolbar buttons, keyboard shortcuts) need to trigger operations without knowing the receiver or the operation's implementation
- The application requires multi-level undo and redo beyond a single "last action"
- Operations need to be queued, scheduled, logged to disk, or replayed after a crash
- Multiple UI surfaces (menu, button, keyboard shortcut) must trigger the same operation without code duplication
- Operations should be combinable into macro sequences that execute as a unit
Before starting, confirm:
- Can you identify at least one **invoker** (the object that triggers the request β€” e.g., a menu item, button, toolbar) and one **receiver** (the object that knows how to perform the operation β€” e.g., a document, model, service)?
- Do operations need to be reversible? If so, can each operation store enough state to reverse itself, or does it need an external snapshot (Memento)?
If unsure whether Command is the right pattern, invoke `behavioral-pattern-selector` first and confirm Command is recommended.
---
πŸ’‘ Examples

Example 1: Document Editor with Multi-Level Undo

Scenario: A text editor with menus for Cut, Copy, Paste, and Bold. Users expect unlimited undo/redo accessible from Edit > Undo and Edit > Redo, and from Ctrl+Z / Ctrl+Y. The same Cut command should be triggerable from the menu, the toolbar, and the keyboard shortcut.

Trigger: "We need multi-level undo for edit operations and the same command needs to work from three different places in the UI."

Process:

  • Step 1: Invoker = MenuItem + ToolbarButton + KeyboardHandler. Receiver = Document. Client = Application.
  • Step 2: Full undo protocol β€” Command interface includes Execute, Unexecute, Reversible.
  • Step 3: CutCommand captures the cut selection and clipboard content at Execute time. BoldCommand captures the affected range and original font at Execute time.
  • Step 4: CommandHistory with present-line pointer. Edit > Undo calls history.Undo(). Edit > Redo calls history.Redo().
  • Step 6: Application creates one CutCommand(document), assigns it to the menu item, toolbar button, and keyboard handler. All three share the same instance.
  • Output:

  • CutCommand.Execute() saves selected text to clipboard, deletes from document, records deleted range + content
  • CutCommand.Unexecute() re-inserts recorded content at recorded range, updates clipboard
  • History state after three edits: [CutCmd | BoldCmd | PasteCmd] | (present at end)
  • After two undos: [CutCmd | BoldCmd | PasteCmd] (present points at CutCmd)
  • After typing a new character: [CutCmd | TypeCmd] (BoldCmd and PasteCmd discarded)

  • Example 2: Database Transaction System

    Scenario: A database management system needs to support atomic transactions as a sequence of insertions, updates, and deletions. The whole transaction must be undoable as a unit if it fails partway through. Operations need to be logged to disk so they can be replayed after a crash.

    Trigger: "We need to group database operations into a transaction and undo the whole thing if any step fails."

    Process:

  • Step 1: Invoker = TransactionManager. Receiver = Database. Client = Application.
  • Step 2: Full undo interface. Each operation also implements Store() / Load() for crash-recovery logging.
  • Step 3: InsertCommand captures the inserted row's primary key for Unexecute (DELETE by key). UpdateCommand captures the original row values. DeleteCommand captures the full deleted row.
  • Step 5: Transaction = MacroCommand. On success, the MacroCommand is placed on history as one unit. On failure midway, MacroCommand.Unexecute() reverses completed sub-commands in reverse order.
  • Log persistence: after Execute, each sub-command is serialized to a log file. On crash recovery, the log is read and each command's Execute is re-applied.
  • Output:

  • Transaction of [InsertCmd, UpdateCmd, DeleteCmd] executes forward; on failure after UpdateCmd, reverse unexecution: [UpdateCmd.Unexecute(), InsertCmd.Unexecute()] β€” DeleteCmd was never executed so it is not reversed
  • History after commit: one MacroCommand on the history list, undoable as a unit
  • Crash recovery: replay log by re-calling Execute on each logged command

  • Example 3: Lexi MenuItem-Command Case Study (from GoF)

    Scenario: The Lexi document editor (GoF chapter 2) has dozens of user operations accessible via pull-down menus and keyboard shortcuts. Operations include paste, change font, open document, quit, and save. Some are undoable (paste, font change), some are not (quit, save). MenuItems must not be subclassed per operation β€” one MenuItem class must serve all cases.

    Trigger: "We have too many menu item subclasses β€” one per operation. Adding a new operation requires a new subclass."

    Process:

  • Step 1: Invoker = MenuItem. Receivers = Document (paste, font), Application (open, quit). Client = Application (configures menus at startup).
  • Step 2: Command interface has Execute. Undo interface has Unexecute + Reversible.
  • Step 3:
  • - PasteCommand(document): Execute calls document.Paste(). Undoable β€” stores clipboard content. - FontCommand(document, font, range): Execute saves original font, applies new font. Undoable. - OpenCommand(application): Execute prompts user for filename, creates Document, calls application.Add(document), opens it. Not the typical receiver-delegation pattern β€” the command does all the work itself because there is no pre-existing receiver. - QuitCommand(application): Execute checks if document is modified; if so, calls save.Execute(), then quits. Reversible() = false β€” not placed on history.
  • Step 6: Application creates all ConcreteCommand instances at startup, assigns each to the appropriate MenuItem. MenuItem.Clicked() calls history.ExecuteCommand(this._command).
  • Output:

  • One MenuItem class handles all operations β€” the operation is entirely in the Command
  • Edit menu's Undo item calls history.Undo() β€” which calls Unexecute() on the last reversible command
  • QuitCommand does not appear in undo history
  • Font change on text already in that font: FontCommand.Reversible() checks if font actually changed; returns false if not, preventing a no-op undo entry

  • View on ClawHub
    TERMINAL
    clawhub install bookforge-command-pattern-implementor

    πŸ§ͺ Use this skill with your agent

    Most visitors already have an agent. Pick your environment, install or copy the workflow, then run the smoke-test prompt above.

    πŸ” Can't find the right skill?

    Search 60,000+ AI agent skills β€” free, no login needed.

    Search Skills β†’