Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
iluwatar committed Aug 29, 2020
1 parent a4f2d14 commit 675b2f1
Showing 1 changed file with 51 additions and 21 deletions.
72 changes: 51 additions & 21 deletions command/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,34 @@ tags:
---

## 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.

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.
> 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.
> 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.
Here's the sample code with wizard and goblin. Let's start from the `Wizard` class.

```java
public class Wizard {
Expand Down Expand Up @@ -149,7 +156,7 @@ public class ShrinkSpell implements Command {
}
```

And last we have the goblin who's the target of the spells.
Finally, we have the goblin who's the target of the spells.

```java
public abstract class Target {
Expand Down Expand Up @@ -199,44 +206,67 @@ public class Goblin extends Target {
}
```

Finally here's the whole example in action.
Here's the whole example in action.

```java
var wizard = new Wizard();
var goblin = new Goblin();
goblin.printStatus();
// Goblin, [size=normal] [visibility=visible]
wizard.castSpell(new ShrinkSpell(), goblin);
// Wizard casts Shrink spell at Goblin
goblin.printStatus();
// Goblin, [size=small] [visibility=visible]
wizard.castSpell(new InvisibilitySpell(), goblin);
// Wizard casts Invisibility spell at Goblin
goblin.printStatus();
// Goblin, [size=small] [visibility=invisible]
wizard.undoLastSpell();
// Wizard undoes Invisibility spell
goblin.printStatus();
```

Here's the program output:

```java
// Goblin, [size=normal] [visibility=visible]
// Wizard casts Shrink spell at Goblin
// Goblin, [size=small] [visibility=visible]
// Wizard casts Invisibility spell at Goblin
// Goblin, [size=small] [visibility=invisible]
// Wizard undoes Invisibility spell
// Goblin, [size=small] [visibility=visible]
```

## Class diagram

![alt text](./etc/command.png "Command")

## Applicability
Use the Command pattern when you want to

* 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 called at a later point. Commands are an object-oriented replacement for callbacks.
* 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 and fulfill the request there
* 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 Unexecute operation that reverses the effects of a previous call to execute. Executed commands are stored in a history list. Unlimited-level undo and redo is achieved by traversing this list backwards and forwards calling unexecute and execute, respectively
* 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 the execute operation
* 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 system with new transactions
Use the Command pattern when you want to:

* 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
called at a later point. Commands are an object-oriented replacement for callbacks.
* 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
and fulfill the request there.
* 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
un-execute and execute, respectively.
* 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
the execute operation.
* 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
system with new transactions.

## Typical Use Case

* to keep a history of requests
* implement callback functionality
* implement the undo functionality
* To keep a history of requests
* Implement callback functionality
* Implement the undo functionality

## Real world examples

Expand Down

0 comments on commit 675b2f1

Please sign in to comment.