2015-08-13 23:54:40 +02:00
---
layout: pattern
title: Command
folder: command
2015-08-15 18:03:05 +02:00
permalink: /patterns/command/
2015-08-20 21:40:07 +02:00
categories: Behavioral
2016-08-20 20:49:28 +05:30
tags:
2019-12-13 22:22:11 +02:00
- Gang of Four
2015-08-13 23:54:40 +02:00
---
2016-01-03 21:14:30 +01:00
## Also known as
2020-08-29 16:10:59 +03:00
2016-01-03 21:14:30 +01:00
Action, Transaction
2015-11-04 21:13:32 +02:00
2016-01-03 21:14:30 +01:00
## Intent
2020-08-29 16:10:59 +03:00
2020-09-30 17:56:12 +02:00
Encapsulate a request as an object, thereby letting you parameterize clients with different
2020-08-29 16:10:59 +03:00
requests, queue or log requests, and support undoable operations.
2020-07-15 11:03:23 +03:00
## Explanation
Real world example
2020-09-30 17:56:12 +02:00
> 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
2020-08-29 16:10:59 +03:00
> the spells one by one. Each spell here is a command object that can be undone.
2020-07-15 11:03:23 +03:00
In plain words
> Storing requests as command objects allows performing an action or undoing it at a later time.
Wikipedia says
2020-09-30 17:56:12 +02:00
> 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
2020-08-29 16:10:59 +03:00
> a later time.
2020-07-15 11:03:23 +03:00
**Programmatic Example**
2020-08-29 16:10:59 +03:00
Here's the sample code with wizard and goblin. Let's start from the `Wizard` class.
2020-07-15 11:03:23 +03:00
```java
2021-03-13 13:19:21 +01:00
@Slf4j
2020-07-15 11:03:23 +03:00
public class Wizard {
2020-07-30 20:28:47 +03:00
private final Deque< Command > undoStack = new LinkedList< >();
private final Deque< Command > redoStack = new LinkedList< >();
2020-07-15 11:03:23 +03:00
public Wizard() {}
2020-09-30 17:56:12 +02:00
public void castSpell(Runnable runnable) {
runnable.run();
undoStack.offerLast(runnable);
2020-07-15 11:03:23 +03:00
}
public void undoLastSpell() {
if (!undoStack.isEmpty()) {
var previousSpell = undoStack.pollLast();
redoStack.offerLast(previousSpell);
2020-09-30 17:56:12 +02:00
previousSpell.run();
2020-07-15 11:03:23 +03:00
}
}
public void redoLastSpell() {
if (!redoStack.isEmpty()) {
var previousSpell = redoStack.pollLast();
undoStack.offerLast(previousSpell);
2020-09-30 17:56:12 +02:00
previousSpell.run();
2020-07-15 11:03:23 +03:00
}
}
@Override
public String toString() {
return "Wizard";
}
}
```
2020-09-30 17:56:12 +02:00
Next, we have the goblin who's the target of the spells.
2020-07-15 11:03:23 +03:00
```java
2021-03-13 13:19:21 +01:00
@Slf4j
2020-07-15 11:03:23 +03:00
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";
}
2020-09-30 17:56:12 +02:00
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);
}
2020-07-15 11:03:23 +03:00
}
```
2020-09-30 17:56:12 +02:00
Finally we have the wizard in main function who casts spell
```java
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();
```
2020-08-29 16:10:59 +03:00
Here's the whole example in action.
2020-07-15 11:03:23 +03:00
```java
var wizard = new Wizard();
var goblin = new Goblin();
2020-09-30 17:56:12 +02:00
goblin.printStatus();
wizard.castSpell(goblin::changeSize);
2020-07-15 11:03:23 +03:00
goblin.printStatus();
2020-09-30 17:56:12 +02:00
wizard.castSpell(goblin::changeVisibility);
2020-07-15 11:03:23 +03:00
goblin.printStatus();
2020-09-30 17:56:12 +02:00
wizard.undoLastSpell();
2020-07-15 11:03:23 +03:00
goblin.printStatus();
2020-09-30 17:56:12 +02:00
2020-07-15 11:03:23 +03:00
wizard.undoLastSpell();
goblin.printStatus();
2020-09-30 17:56:12 +02:00
wizard.redoLastSpell();
goblin.printStatus();
wizard.redoLastSpell();
goblin.printStatus();
2020-08-29 16:10:59 +03:00
```
Here's the program output:
```java
2020-09-30 17:56:12 +02:00
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]
2020-07-15 11:03:23 +03:00
```
2015-08-13 23:54:40 +02:00
2019-12-07 20:01:13 +02:00
## Class diagram
2020-08-29 16:10:59 +03:00
2015-08-13 23:54:40 +02:00

2016-01-03 21:14:30 +01:00
## Applicability
2015-08-13 23:54:40 +02:00
2020-08-29 16:10:59 +03:00
Use the Command pattern when you want to:
2020-09-30 17:56:12 +02:00
* Parameterize objects by an action to perform. You can express such parameterization in a
procedural language with a callback function, that is, a function that's registered somewhere to be
2020-08-29 16:10:59 +03:00
called at a later point. Commands are an object-oriented replacement for callbacks.
2020-09-30 17:56:12 +02:00
* Specify, queue, and execute requests at different times. A Command object can have a lifetime
independent of the original request. If the receiver of a request can be represented in an address
space-independent way, then you can transfer a command object for the request to a different process
2020-08-29 16:10:59 +03:00
and fulfill the request there.
2020-09-30 17:56:12 +02:00
* Support undo. The Command's execute operation can store state for reversing its effects in the
command itself. The Command interface must have an added un-execute operation that reverses the
effects of a previous call to execute. The executed commands are stored in a history list.
Unlimited-level undo and redo is achieved by traversing this list backwards and forwards calling
2020-08-29 16:10:59 +03:00
un-execute and execute, respectively.
2020-09-30 17:56:12 +02:00
* Support logging changes so that they can be reapplied in case of a system crash. By augmenting the
Command interface with load and store operations, you can keep a persistent log of changes.
Recovering from a crash involves reloading logged commands from disk and re-executing them with
2020-08-29 16:10:59 +03:00
the execute operation.
2020-09-30 17:56:12 +02:00
* Structure a system around high-level operations build on primitive operations. Such a structure is
common in information systems that support transactions. A transaction encapsulates a set of changes
to data. The Command pattern offers a way to model transactions. Commands have a common interface,
letting you invoke all transactions the same way. The pattern also makes it easy to extend the
2020-08-29 16:10:59 +03:00
system with new transactions.
2015-08-13 23:54:40 +02:00
2016-01-03 21:14:30 +01:00
## Typical Use Case
2015-08-13 23:54:40 +02:00
2020-08-29 16:10:59 +03:00
* To keep a history of requests
* Implement callback functionality
* Implement the undo functionality
2015-08-13 23:54:40 +02:00
2016-01-03 21:14:30 +01:00
## Real world examples
2015-08-13 23:54:40 +02:00
2015-08-15 18:03:05 +02:00
* [java.lang.Runnable ](http://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html )
2018-12-03 18:58:20 +05:30
* [org.junit.runners.model.Statement ](https://github.com/junit-team/junit4/blob/master/src/main/java/org/junit/runners/model/Statement.java )
2016-02-15 18:21:34 +05:30
* [Netflix Hystrix ](https://github.com/Netflix/Hystrix/wiki )
2016-08-20 20:49:28 +05:30
* [javax.swing.Action ](http://docs.oracle.com/javase/8/docs/api/javax/swing/Action.html )
2015-09-22 18:25:56 +05:30
2016-01-03 21:14:30 +01:00
## Credits
2015-09-22 18:25:56 +05:30
2020-07-06 13:31:07 +03:00
* [Design Patterns: Elements of Reusable Object-Oriented Software ](https://www.amazon.com/gp/product/0201633612/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0201633612&linkCode=as2&tag=javadesignpat-20&linkId=675d49790ce11db99d90bde47f1aeb59 )
2020-07-07 18:05:11 +03:00
* [Head First Design Patterns: A Brain-Friendly Guide ](https://www.amazon.com/gp/product/0596007124/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596007124&linkCode=as2&tag=javadesignpat-20&linkId=6b8b6eea86021af6c8e3cd3fc382cb5b )
2020-07-07 18:44:00 +03:00
* [Refactoring to Patterns ](https://www.amazon.com/gp/product/0321213351/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321213351&linkCode=as2&tag=javadesignpat-20&linkId=2a76fcb387234bc71b1c61150b3cc3a7 )
2020-07-07 20:05:35 +03:00
* [J2EE Design Patterns ](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94 )