Command pattern is used to store a full execution process in an object. The command object is independent of any other dependencies and can be executed and/or passed without any additional information.
NOTE
This article demonstrates Command pattern implementations in Golang.
Check the link below to check the details of the Command Pattern-
Implementation
Follow the steps below-
- Define an interface for ensuring a common interface for all the commands. Make sure to have methods for the execution and remove/undo the commands.
- Define the command structs and implement the interface for those structs.
- Create a struct for the control.
- In the control struct, define methods for adding and removing command elements. In the methods for adding/removing call the methods from the command.
- In the control structure, maintain a list of commands. While adding the element call the add/execution method from the command, and also add that to the list. Remove the command from the list, in case of removing the element.
Examples
Here are a few examples of Command pattern implementation in Golang.
Example #1: UI Elements
Let’s take the example of printing UI elements. Let’s take a look at the class diagram first.
Command Interface
- Create file “ui_command.go”.
- Create interface “UiCommand”.
- Declare methods as per requirement – “Print”, “Remove”.
// ui_command.go
package main
type UiCommand interface {
Print()
Remove()
}
Button Struct
- Create file “button_ui.go”.
- Create struct “ButtonUi”.
- Declare a field named “name”.
- Create method “NewButtonUi”, this will create a new struct and return that. Also, set the value of “name”.
- Implement the “UiCommand” interface for the struct. Define methods “Print” and “Remove” for the interface implementation.
// button_ui.go
package main
import "fmt"
type ButtonUi struct {
name string
}
func NewButtonUi(name string) (buttonUi *ButtonUi) {
buttonUi = &ButtonUi{}
buttonUi.name = name
return
}
func (buttonUi *ButtonUi) Print() {
fmt.Printf("Printing %s Butonn", buttonUi.name)
}
func (buttonUi *ButtonUi) Remove() {
fmt.Printf("Removing %s Buttonn", buttonUi.name)
}
Input Element Struct
- Create file “input_ui.go”.
- Create struct “InputUi”.
- Create method “NewInputUi”, this will create a new struct and return that.
- Implement the “UiCommand” interface for the struct. Define methods “Print” and “Remove” for the interface implementation.
// input_ui.go
package main
import "fmt"
type InputUi struct {
}
func NewInputUi() (inputUi *InputUi) {
inputUi = &InputUi{}
return
}
func (inputUi *InputUi) Print() {
fmt.Println("Printing Input")
}
func (inputUi *InputUi) Remove() {
fmt.Println("Removing Input")
}
Table Element Struct
- Create file “table_ui.go”.
- Create struct “TableUi”.
- Create method “NewTableUi”, create a new struct, and return that.
- Implement the “UiCommand” interface for the struct.
// table_ui.go
package main
import "fmt"
type TableUi struct {
}
func NewTableUi() (tableUi *TableUi) {
tableUi = &TableUi{}
return
}
func (tableUi *TableUi) Print() {
fmt.Println("Printing Table")
}
func (tableUi *TableUi) Remove() {
fmt.Println("Removing Table")
}
UI Element Control Struct
- Create file “ui_control.go”.
- Create struct “UiControl”.
- Declare field “commandList”, a slice of “UiCommand”.
- Create method “NewUiControl”, to create a new struct, and return that.
- Define method “AddElement”. In the implementation add code for printing the element(call the “Print” method). Also add the command to the “commandList”.
- Define method “RemoveElement”. In the implementation call the “Remove” method of the element, and also remove the element from “commandList”.
- As a utility method, we have an “Undo” method here, to undo the last command. which in turn uses the “RemoveElement” method.
// ui_control.go
package main
type UiControl struct {
commandList []UiCommand
}
func NewUiControl() (uiControl *UiControl) {
uiControl = &UiControl{}
return
}
func (uiControl *UiControl) AddElement(uiCommand UiCommand) {
// Execute command
uiCommand.Print()
// Add to list
uiControl.commandList = append(uiControl.commandList, uiCommand)
}
func (uiControl *UiControl) RemoveElement(uiCommand UiCommand) {
// Remove element
uiCommand.Remove()
// Remove from list
newList := []UiCommand{}
for _, elem := range uiControl.commandList {
if elem != uiCommand {
newList = append(newList, elem)
}
}
uiControl.commandList = newList
}
func (uiControl *UiControl) Undo() {
uiCommand := uiControl.commandList[len(uiControl.commandList) - 1]
uiControl.RemoveElement(uiCommand)
}
Demo
For using the implementation, create an “UiControl”. Then we can add/remove elements from that.
// main.go
package main
func main() {
uiControl := NewUiControl()
inputUi := NewInputUi()
tableUi := NewTableUi()
buttonUi := NewButtonUi("Submit")
uiControl.AddElement(inputUi)
uiControl.AddElement(tableUi)
uiControl.AddElement(buttonUi)
uiControl.RemoveElement(tableUi)
uiControl.AddElement(NewButtonUi("Cancel"))
uiControl.AddElement(NewTableUi())
uiControl.AddElement(NewInputUi())
uiControl.AddElement(NewButtonUi("Wrong button"))
uiControl.Undo()
uiControl.Undo()
}
Output
Output will be as below-
Printing Input
Printing Table
Printing Submit Buton
Removing Table
Printing Cancel Buton
Printing Table
Printing Input
Printing Wrong button Buton
Removing Wrong button Button
Removing Input
Source Code
Use the following link to get the source code:
Example | Source Code Link |
---|---|
Example #1: UI Elements | GitHub |
Other Code Implementations
Use the following links to check Command pattern implementation in other programming languages.