Command Execution System

Design a system that registers named commands and runs them on demand.

1, Each command performs some work and reports a result. Every time one runs, the system appends it to a history.

2, Also model every action as an object rather than a bare function call. The system can store the command in a list, log its name, and call it again later.

3, Each command knows how to apply its effect and how to roll it back. Because both live on the same object, the system can simply walk the history backward, ask each command to undo itself, and restore the earlier state step by step.

Interfaces

A Command contract, plus an executor that runs and tracks them:

class Command:
    def execute(self): ...        # do the work, return a result
    def undo(self): ...           # reverse the effect of execute()
    def name(self): ...           # identifier for history/logging


class CommandExecutor:
    def register(self, name, command): ...   # make a command runnable by name
    def run(self, name, *args): ...          # execute it, record it in history
    def undo(self): ...                       # reverse the most recent command
    def redo(self): ...                       # re-apply the most recently undone
    def history(self): ...                    # ordered list of what has run

Operations

  • register(name, command): bind a name to a command so it can be invoked.
  • run(name, ...args): execute the named command, return its result, and append it to history.
  • undo(): reverse the last executed command and return what was undone.
  • redo(): re-execute the last undone command.
  • history(): the commands that have run, in execution order.

Requirements

  • Unknown command names fail clearly rather than silently doing nothing.
  • undo reverses commands in LIFO order — most recent first.
  • Running a new command after an undo clears the redo stack (no branching history).
  • A command with no meaningful inverse may declare itself non-undoable; the system must reject undoing it instead of corrupting state.
  • The design should extend to new command types without changing the executor.

Examples

ex = CommandExecutor()
ex.register("add", AddToBalance(account))

ex.run("add", 100)     # balance 0 -> 100, history: [add]
ex.run("add", 50)      # balance 100 -> 150, history: [add, add]

ex.undo()              # balance 150 -> 100  (reverses the +50)
ex.undo()              # balance 100 -> 0    (reverses the +100)
ex.redo()              # balance 0 -> 100    (re-applies the +100)

Think about it

A command runs "set X to 9", and later you call undo — but the old value is already gone.

Follow-ups

  • How would you bundle several commands into one macro that undoes as a single unit?

  • If you persisted the history to a log, how would you replay it to rebuild state after a restart?

  • And more...

Databricks Crash Course

Fullset Newest Databricks Coding/System Design Questions, Optimal Solutions and Explanations.

Step_1 Matched with a FAANG+ Senior Engineer

Step_2 Fullset Databricks Coding/System Design Questions

Step_3 Solutions + step by step Explanation

Check it out