1.1 Definition and Concept
The command pattern is a behavioral design pattern that allows encapsulating a request as an object, so that you can parameterize the client with different requests.
1.2 Purpose of the Command Pattern
The main purpose of the command pattern is to decouple the sender and receiver. By encapsulating the request into an object, the sender only needs to interact with the command object, without directly interacting with the receiver.
2. Characteristics and Advantages of the Command Pattern
The command pattern has the following characteristics and advantages:
- Encapsulating the request into an object decouples the sender and receiver.
- It can queue requests, record logs, and perform undo operations.
- New commands can be extended without changing the original code.
3. Examples of Practical Applications of the Command Pattern
The command pattern is applicable in the following scenarios:
- Needing to decouple the request from the object that performs the command.
- Supporting undo and redo operations.
- Executing a set of operations in a queued manner.
4.1 UML Class Diagram
4.2 Example Introduction
In this example, we will create a simple implementation of the command pattern. Suppose we have a TV as the receiver, capable of performing the actions of turning on and off. We also have a remote controller as the invoker, which can set specific commands and execute them.
4.3.1 Define the Command Interface
type ICommand interface {
Execute()
}
4.3.2 Implement Concrete Command Class
type ConcreteCommand struct {
receiver IReceiver
}
func (c *ConcreteCommand) Execute() {
c.receiver.Action()
}
4.3.3 Define the Receiver Interface
type IReceiver interface {
Action()
}
4.3.4 Implement Concrete Receiver Class
type Receiver struct {}
func (r *Receiver) Action() {
fmt.Println("Performing action")
}
4.3.5 Implement the Invoker Role
type Invoker struct {
command ICommand
}
func (i *Invoker) SetCommand(command ICommand) {
i.command = command
}
func (i *Invoker) ExecuteCommand() {
i.command.Execute()
}
4.3.6 Client Code Example
func main() {
receiver := &Receiver{}
command := &ConcreteCommand{receiver: receiver}
invoker := &Invoker{}
invoker.SetCommand(command)
invoker.ExecuteCommand()
}
5. Difference Between Command Pattern and Strategy Pattern
The command pattern and the strategy pattern are similar to some extent, as both encapsulate certain behaviors into objects. The difference lies in that the command pattern is mainly used to encapsulate requests as objects and implement functions such as undo and execute queues, while the strategy pattern is mainly used to encapsulate a series of algorithms and dynamically choose one algorithm to execute at runtime.
The command pattern is more suitable for operations like logging and accounting, while the strategy pattern is more suitable for flexible changes in business logic.