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

Golang Command Pattern

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.