Problem statement
Design the object model and public APIs for an undo/redo manager: the reusable core that lets an application record every edit as a reversible operation and step the user backward and forward through their history. Design the command abstraction and the two-stack history engine — not the editor, document, or widgets that produce the edits.
Operating context. A single-user, single-threaded desktop-style application (a drawing tool, a text editor, a form builder) drives the manager from its UI thread. Each user action — move a shape, type a run of characters, delete a selection — is captured as a command that knows how to apply itself and how to reverse itself. The manager keeps a bounded history: past commands on an undo stack, undone commands on a redo stack. Pressing undo pops the last command, reverses it, and pushes it onto redo; pressing redo does the mirror. Performing a brand-new action after some undos discards the redo branch. Some interactions must be grouped so one keystroke reverses the whole group (drag-resize that moves and scales together, a find-and-replace-all). The history has a capacity cap so long sessions do not grow without bound; the oldest entries are dropped.
Out of scope. The concrete document model and the specific edits themselves (shapes, text runs); the rendering/UI layer and keyboard-shortcut wiring; persisting or serializing history across app restarts; multi-user or collaborative editing and operational-transform/CRDT merge; and threading/async — assume all calls happen on one thread.
What to produce. The class hierarchy (the command interface with do/undo, the manager that owns both stacks, and a composite command that batches children), the public API each type exposes, and the state the manager moves through as actions, undos, and redos interleave. Be explicit about: the exact command contract and its invariants; how the two stacks evolve on execute/undo/redo and precisely when the redo stack is cleared; how a composite command applies and reverses its children in the correct order; how the capacity cap evicts the oldest history without corrupting the stacks; how transient grouping (open a batch, add several commands, commit or abort) is exposed; and how the manager stays generic so any application supplies its own command types without the manager knowing their concrete classes.
Requirements
This assessment is a Premium feature.
The statement above is free to read. The functional and non-functional requirements, and the graded canvas that scores your design against them, come with Premium.
Topics
- System Design LLD
- Patterns Command
- Patterns Composite
- Oop Solid
- Extensibility