Command Pattern: Text Editor Application
Domain: Text Editor with Undo/Redo
We will design a text editor supporting bold, italic, and delete operations with full undo/redo capability. Each formatting action becomes a command that can be reversed.
Design Decisions
State Storage: DeleteCommand stores deletedText so undo can restore it. BoldCommand stores start and end positions to reverse formatting. Each command captures whatever state is needed to reverse itself.
CommandHistory as Invoker: The CommandHistory class acts as invoker and maintains undo/redo stacks. When execute(cmd) is called, it executes the command, pushes it to undoStack, and clears redoStack. When undo() is called, it pops from undoStack, calls cmd.undo(), and pushes to redoStack. This centralized history management is cleaner than scattered undo logic.
TextEditor as Receiver: The TextEditor contains the actual document manipulation logic. It knows nothing about commands. Methods like applyBold() and deleteText() are reusable whether called from commands or elsewhere.
Execution Example
First, user selects text from position 5 to 10 and clicks the Bold button. Second, UI creates BoldCommand(editor, 5, 10) and passes it to history.execute(boldCmd). Third, CommandHistory calls boldCmd.execute(), which calls editor.applyBold(5, 10). Fourth, CommandHistory pushes boldCmd onto undoStack. Later, if user presses Ctrl+Z, CommandHistory pops boldCmd, calls boldCmd.undo(), which calls editor.removeBold(5, 10), and pushes boldCmd to redoStack. If user performs a new action, redoStack is cleared because redo is no longer valid after a new operation.
MacroCommand would hold a list of commands and execute/undo them all in sequence, demonstrating the Composite Pattern combined with Command Pattern.