Command Pattern
# Command Pattern
The Command Pattern is a data-driven design pattern that belongs to the behavioral design pattern category.
The Command Pattern encapsulates a request as an object, thereby allowing you to parameterize clients with different requests, queue or log requests, and support undoable operations.
**Command Pattern Structure Diagram:**
!(#)
## Introduction
### Intent
Encapsulate a request as an object, allowing the user to parameterize clients with different requests.
### Main Problem Solved
* Solves the problem of tight coupling between the invoker and the receiver in a software system, especially in scenarios that require logging, undo/redo, or transaction processing for actions.
### Use Cases
* Use the Command Pattern to decouple the invoker and receiver when you need to log, undo/redo, or process transactions for actions.
### Implementation Approach
* **Define the Command Interface**: An interface that all commands must implement.
* **Create Concrete Commands**: Concrete classes that implement the command interface and contain the method to execute the request.
* **Invoker**: Holds the command object and triggers the command's execution.
* **Receiver**: The object that actually executes the command.
### Key Code
* **Receiver**: The actual object that executes the command.
* **Command**: Defines the interface for executing commands.
* **Invoker**: The entry point that uses the command object.
### Application Examples
* **Struts 1**: ActionServlet acts as the Invoker, and the model layer classes act as concrete Commands.
### Advantages
1. **Reduces Coupling**: Decouples the invoker and the receiver.
2. **Easy to Extend**: New commands can be easily added to the system.
### Disadvantages
* **Too Many Command Classes**: The system may end up with too many concrete command classes, increasing system complexity.
### Usage Suggestions
* In GUIs, each button or menu item can be considered a command.
* Use the Command Pattern in scenarios that need to simulate command-line operations.
### Notes
* If the system needs to support undo and redo operations for commands, the Command Pattern is a suitable choice.
### Structure
**It mainly involves the following core roles:**
* **Command:**
* Defines the interface for performing operations, typically containing an `execute` method to invoke the specific operation.
* **ConcreteCommand:**
* Implements the command interface and is responsible for executing the specific operation. It usually contains a reference to the receiver and completes the request processing by calling the receiver's methods.
* **Receiver:**
* Knows how to perform the operations associated with the request; it is the object that actually executes the command.
* **Invoker (Requester):**
* The object that sends the command. It contains a command object and can trigger the command's execution. The invoker does not handle the request directly but does so by passing the request to the command object.
* **Client:**
* Creates the concrete command object and sets its receiver, then gives the command object to the invoker for execution.
## Implementation
We first create the command interface _Order_, then create the _Stock_ class as the request. The concrete command classes _BuyStock_ and _SellStock_ implement the _Order_ interface to perform the actual command processing. We create the _Broker_ class as the invoker object, which accepts orders and can place them.
The _Broker_ object uses the Command Pattern to determine which object executes which command based on the command type. The _CommandPatternDemo_ class uses the _Broker_ class to demonstrate the Command Pattern.
!(#)
### Step 1
Create a command interface.
## Order.java
public interface Order{void execute(); }
### Step 2
Create a request class.
## Stock.java
public class Stock{private String name = "ABC"; private int quantity = 10; public void buy(){System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] bought"); }public void sell(){System.out.println("Stock [ Name: "+name+", Quantity: " + quantity +" ] sold"); }}
### Step 3
Create concrete classes that implement the _Order_ interface.
## BuyStock.java
public class BuyStock implements Order{private Stock abcStock; public BuyStock(Stock abcStock){this.abcStock = abcStock; }public void execute(){abcStock.buy(); }}
## SellStock.java
public class SellStock implements Order{private Stock abcStock; public SellStock(Stock abcStock){this.abcStock = abcStock; }public void execute(){abcStock.sell(); }}
### Step 4
Create the command invoker class.
## Broker.java
import java.util.ArrayList; import java.util.List; public class Broker{private ListorderList = new ArrayList(); public void takeOrder(Order order){orderList.add(order); }public void placeOrders(){for(Order order : orderList){order.execute(); }orderList.clear(); }}
### Step 5
Use the Broker class to accept and execute commands.
## CommandPatternDemo.java
public class CommandPatternDemo{public static void main(String[]args){Stock abcStock = new Stock(); BuyStock buyStockOrder = new BuyStock(abcStock); SellStock sellStockOrder = new SellStock(abcStock); Broker broker = new Broker(); broker.takeOrder(buyStockOrder); broker.takeOrder(sellStockOrder); broker.placeOrders(); }}
### Step 6
Execute the program, output the result:
Stock [ Name: ABC, Quantity: 10 ] bought Stock [ Name: ABC, Quantity: 10 ] sold
YouTip