Command
Also known as
Action, Transaction
Intent
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
Explanation
Real-world example
There is a wizard casting spells on a goblin. The spells are executed on the goblin one by one. The first spell shrinks the goblin and the second makes him invisible. Then the wizard reverses the spells one by one. Each spell here is a command object that can be undone.
In plain words
Storing requests as command objects allows performing an action or undoing it at a later time.
Wikipedia says
In object-oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time.
Programmatic Example
Here's the sample code with wizard and goblin. Let's start from the Wizard
class.
@Slf4j
public class Wizard {
private final Deque<Command> undoStack = new LinkedList<>();
private final Deque<Command> redoStack = new LinkedList<>();
public Wizard() {}
public void castSpell(Runnable runnable) {
runnable.run();
undoStack.offerLast(runnable);
}
public void undoLastSpell() {
if (!undoStack.isEmpty()) {
var previousSpell = undoStack.pollLast();
redoStack.offerLast(previousSpell);
previousSpell.run();
}
}
public void redoLastSpell() {
if (!redoStack.isEmpty()) {
var previousSpell = redoStack.pollLast();
undoStack.offerLast(previousSpell);
previousSpell.run();
}
}
@Override
public String toString() {
return "Wizard";
}
}
Next, we have the goblin who's the target of the spells.
@Slf4j
public abstract class Target {
private Size size;
private Visibility visibility;
public Size getSize() {
return size;
}
public void setSize(Size size) {
this.size = size;
}
public Visibility getVisibility() {
return visibility;
}
public void setVisibility(Visibility visibility) {
this.visibility = visibility;
}
@Override
public abstract String toString();
public void printStatus() {
LOGGER.info("{}, [size={}] [visibility={}]", this, getSize(), getVisibility());
}
}
public class Goblin extends Target {
public Goblin() {
setSize(Size.NORMAL);
setVisibility(Visibility.VISIBLE);
}
@Override
public String toString() {
return "Goblin";
}
public void changeSize() {
var oldSize = getSize() == Size.NORMAL ? Size.SMALL : Size.NORMAL;
setSize(oldSize);
}
public void changeVisibility() {
var visible = getVisibility() == Visibility.INVISIBLE
? Visibility.VISIBLE : Visibility.INVISIBLE;
setVisibility(visible);
}
}
Finally, we have the wizard in the main function casting spells.
public static void main(String[] args) {
var wizard = new Wizard();
var goblin = new Goblin();
// casts shrink/unshrink spell
wizard.castSpell(goblin::changeSize);
// casts visible/invisible spell
wizard.castSpell(goblin::changeVisibility);
// undo and redo casts
wizard.undoLastSpell();
wizard.redoLastSpell();
Here's the whole example in action.
var wizard = new Wizard();
var goblin = new Goblin();
goblin.printStatus();
wizard.castSpell(goblin::changeSize);
goblin.printStatus();
wizard.castSpell(goblin::changeVisibility);
goblin.printStatus();
wizard.undoLastSpell();
goblin.printStatus();
wizard.undoLastSpell();
goblin.printStatus();
wizard.redoLastSpell();
goblin.printStatus();
wizard.redoLastSpell();
goblin.printStatus();
Here's the program output:
Goblin, [size=normal] [visibility=visible]
Goblin, [size=small] [visibility=visible]
Goblin, [size=small] [visibility=invisible]
Goblin, [size=small] [visibility=visible]
Goblin, [size=normal] [visibility=visible]
Goblin, [size=small] [visibility=visible]
Goblin, [size=small] [visibility=invisible]
Class diagram

Applicability
Use the Command pattern when you want to: