← Back to PatternPip

COMMAND / THE IDEA IN A MINUTE

Turn an action
into a request you can keep.

Command puts an action and the information it needs into one object. Other code can run that request without knowing how the work is done.

Think “append this text to this document.” Keep that request, and an editor can run it, remember it and—with an undo method—reverse it.

SEE IT HAPPEN / FOUR SMALL ACTIONS

One edit. A request you can keep.

Try it yourself

Follow one command from creation to redo. You control each step; nothing runs automatically.

YOUR EDITChoosing an edit starts a fresh example.
  1. 1Create
  2. 2Execute
  3. 3Undo
  4. 4Redo

Start with something you want to do.

Choose an edit. First, we’ll put the request into an object—without changing the document yet.

YOUR COMMANDNot created yet

An action, ready to be packaged.

Do what?
—
To what?
—
With what?
—
Saved for undoNothing captured yetCaptured when execute() runs.
waiting to execute
THE DOCUMENTReceiver
notes.txt

Hello

Still Hello. Creating a request has no effect on the text.

HistoryUndo EmptyRedo EmptyOnly a successfully executed edit enters history.

Put the action, document and text together.

The document says Hello. No command has been created yet.

What makes undo possible? We wrote an undo method and saved the previous text. Command gives the request a home; it does not make actions reversible by itself.

WHY ADD THIS OBJECT?

More actions. More controls. One way to run them.

Now imagine Append, Replace and Clear, each available from a button, menu or shortcut. They all need to work with the same undo history.

THE PRESSURE / DIRECT HANDLERS

Every edit can end up doing two jobs.

  • AppendChange text + manage history
  • ReplaceChange text + manage history
  • ClearChange text + manage history

If each handler saves old text and clears redo, every new edit must repeat those rules correctly.

WITH COMMAND / SEPARATE THE JOBS

The edit knows how. History knows when.

  • ControlsCreate and supply a command
  • CommandsOwn each edit and its undo
  • One historyRun, store, undo and redo

Add a compatible Clear command and connect a control to it. History still uses the same execute() and undo() methods.

A shared function or snapshot helper may be enough for a small editor. Command becomes useful when requests need their own behavior and data, and you want to pass them between controls, history or other invokers.

THE STRUCTURE / PUT NAMES TO WHAT YOU SAW

Four roles. One clear responsibility each.

In the editor, controls create a command, history invokes it, and the command calls the document. Here are the pattern names for those jobs.

01 / Client

Creates the request

Editor controls

Chooses an edit, supplies the document and text, and gives the command to history.

02 / Invoker

Runs and keeps it

CommandHistory

Calls execute() or undo() through Command. It manages history without knowing how text is edited.

03 / Command

Knows what to do

InsertText / ReplaceText

Holds the document and text argument. It performs the edit and saves what its undo needs.

04 / Receiver

Does the actual work

TextDocument

Reads and writes the text. It does not know about buttons, shortcuts or undo history.

The shared Command contract is execute() and undo() in this example. Both edit classes implement it. History knows that contract; each command knows its document.

Use it when a request needs more than a click.

Different controls can create the same kind of command. A history can keep commands for undo; another invoker could schedule or log them. Each capability needs its own rules.

Keep the extra structure worthwhile.

One fixed action may need only a function. Command adds objects, and our saved text uses memory. Some effects, such as sending an email, cannot simply be undone.

Choose your next step.