Command Design Pattern in Go

Ramesh Fadatare
2 min readJul 30, 2024

--

1. Definition

The Command Design Pattern is a behavioral design pattern that turns a request into a stand-alone object that contains all information about the request. This transformation allows for parameterizing clients with different requests, queuing requests, and logging their execution. Additionally, it supports undoable operations.

2. Problem Statement

Imagine you’re building an application with various operations. If you hardcode each operation’s execution logic within the invoker, it becomes inflexible, leading to a tightly coupled system that’s hard to extend, maintain, or scale.

3. Solution

Encapsulate each operation within a command object. This command object has a common interface with a method to execute the operation. The invoker simply triggers this method without knowing the specifics of the operation.

4. Real-World Use Cases

1. Undo/redo functionality in software applications.

2. Task scheduling and management systems.

3. Remote control systems where each button press corresponds to a command.

5. Implementation Steps

1. Define a command interface with an Execute() method.

2. Implement concrete command classes for each specific operation, adhering to the command interface.

3. Use an invoker to call the Execute() method on the command object.

4. Optionally, the command object can store the state for undoing the command.

6. Implementation in Go

// Command interface
type Command interface {
Execute()
}

// LightReceiver - an example receiver
type LightReceiver struct{}
func (l *LightReceiver) TurnOn() {
fmt.Println("Light is ON")
}
func (l *LightReceiver) TurnOff() {
fmt.Println("Light is OFF")
}

// Concrete Command
type LightOnCommand struct {
light *LightReceiver
}
func (c *LightOnCommand) Execute() {
c.light.TurnOn()
}
type LightOffCommand struct {
light *LightReceiver
}
func (c *LightOffCommand) Execute() {
c.light.TurnOff()
}

// Invoker
type RemoteControl struct {
command Command
}
func (r *RemoteControl) SetCommand(command Command) {
r.command = command
}
func (r *RemoteControl) PressButton() {
r.command.Execute()
}

// Client code
func main() {
light := &LightReceiver{}
onCommand := &LightOnCommand{light}
offCommand := &LightOffCommand{light}
remote := &RemoteControl{}
remote.SetCommand(onCommand)
remote.PressButton()
remote.SetCommand(offCommand)
remote.PressButton()
}

Output:

Light is ON
Light is OFF

Explanation:

1. The Command interface provides a contract for all concrete command implementations.

2. The LightReceiver is a receiver with methods TurnOn() and TurnOff().

3. LightOnCommand and LightOffCommand are concrete command implementations that encapsulate actions for the LightReceiver.

4. The RemoteControl is an invoker that triggers the command’s Execute() method.

5. The client sets up the commands and the invoker, and then triggers the commands through the invoker.

7. When to use?

Use the Command Pattern when:

1. You need to decouple an object that invokes operations from the object that knows how to execute these operations.

2. You want to support undo/redo functionality.

3. Operations need to be executed at different times or in sequences.

Credit

Command Design Pattern in Go

--

--

Responses (1)