命令模式通过接口和结构体在Golang中实现,1. 定义Command接口及具体命令如LightOnCommand;2. 扩展UndoableCommand支持撤销;3. 利用闭包简化命令定义;4. 使用MacroCommand组合多个命令。

命令模式是一种行为设计模式,它将请求封装为对象,从而使你可以用不同的请求、队列或日志来参数化其他对象。在Golang中,由于没有类和继承的概念,但可以通过接口和结构体很好地实现命令模式。以下是几种常见的Golang命令模式实现方法。
1. 基础命令接口与具体命令
定义一个统一的命令接口,每个具体命令实现该接口的执行方法。
示例:创建一个Command接口,包含Execute()方法:
代码示例:
立即学习“go语言免费学习笔记(深入)”;
package mainimport "fmt"
// Command 接口 type Command interface { Execute() }
// 具体命令:打开灯 type LightOnCommand struct { light *Light }
func (c *LightOnCommand) Execute() { c.light.On() }
// 具体命令:关闭灯 type LightOffCommand struct { light *Light }
func (c *LightOffCommand) Execute() { c.light.Off() }
// 接收者:灯 type Light struct{}
func (l *Light) On() { fmt.Println("灯已打开") }
func (l *Light) Off() { fmt.Println("灯已关闭") }
// 调用者:遥控器 type RemoteControl struct { command Command }
func (r *RemoteControl) PressButton() { if r.command != nil { r.command.Execute() } }
func main() { light := &Light{} onCmd := &LightOnCommand{light: light} offCmd := &LightOffCommand{light: light}
remote := &RemoteControl{} remote.command = onCmd remote.PressButton() // 输出:灯已打开 remote.command = offCmd remote.PressButton() // 输出:灯已关闭}
2. 支持撤销操作的命令
命令对象不仅可以执行操作,还可以提供撤销功能。通过在接口中添加
Undo()方法实现。扩展接口:
type UndoableCommand interface { Execute() Undo() }例如,修改
LightOnCommand:func (c *LightOnCommand) Undo() { c.light.Off() }func (c *LightOffCommand) Undo() { c.light.On() }
调用者可以维护一个历史栈,记录执行过的命令,以便支持批量撤销:
type CommandHistory struct { commands []UndoableCommand }func (h *CommandHistory) Push(cmd UndoableCommand) { h.commands = append(h.commands, cmd) }
func (h *CommandHistory) Pop() UndoableCommand { if len(h.commands) == 0 { return nil } index := len(h.commands) - 1 cmd := h.commands[index] h.commands = h.commands[:index] return cmd }
3. 使用闭包简化命令定义
Golang支持闭包,可以更简洁地实现命令模式,避免定义大量结构体。
将命令封装为函数类型:
type CommandFunc func()func (f CommandFunc) Execute() { f() }
使用示例:
light := &Light{} onFunc := func() { light.On() } offFunc := func() { light.Off() }remote := &RemoteControl{} remote.command = CommandFunc(onFunc) remote.PressButton() // 灯已打开
这种方式适合简单场景,提升开发效率。
4. 宏命令(组合命令)
宏命令是将多个命令组合成一个整体执行。实现方式是让一个命令包含多个子命令。
type MacroCommand struct { commands []Command }func (m *MacroCommand) Execute() { for _, cmd := range m.commands { cmd.Execute() } }
使用示例:
allOn := &MacroCommand{ commands: []Command{onCmd, fanOnCmd}, } remote.command = allOn remote.PressButton() // 同时打开灯和风扇基本上就这些。Golang通过接口和结构体能灵活实现命令模式,无论是基础命令、带撤销功能、闭包封装还是宏命令,都能清晰表达意图,解耦调用者与接收者。实际项目中可根据复杂度选择合适方式。不复杂但容易忽略的是保持命令的单一职责和可测试性。










