Go中实现命令模式支持撤销的关键是定义含Execute()和Undo()方法的Command接口,各具体命令结构体封装必要状态并显式实现双向逻辑,调用器用切片维护历史栈实现单步撤销。

在 Go 中实现命令模式并支持撤销操作,关键在于将每个可执行动作封装为独立的 Command 对象,并维护一个命令历史栈(通常用切片实现),同时要求每个命令自身具备 Execute() 和 Undo() 方法。
Go 没有传统意义上的抽象类,但可通过接口定义契约:
type Command interface {
Execute()
Undo()
}所有具体命令(如“添加用户”、“删除文件”)都必须实现这两个方法。注意:Undo 的逻辑不是自动反向执行,而是由开发者显式编写——比如 DeleteFileCommand 的 Execute() 删除文件,Undo() 就需恢复备份或重新创建该文件。
每个命令结构体需内嵌执行所需的数据,确保 Undo() 有足够上下文回退。例如:
立即学习“go语言免费学习笔记(深入)”;
type AddUserCommand struct {
userStore *[]string
userName string
}
func (c *AddUserCommand) Execute() {
*c.userStore = append(*c.userStore, c.userName)
}
func (c *AddUserCommand) Undo() {
users := *c.userStore
if len(users) > 0 && users[len(users)-1] == c.userName {
*c.userStore = users[:len(users)-1]
}
}Execute() 中修改外部状态后丢失还原依据(如不记录被删文件名就无法恢复)Undo() 应是幂等且尽量轻量的补偿动作用切片模拟栈,按顺序记录已执行命令,提供 Execute()、Undo() 和可选的 Redo():
type CommandInvoker struct {
history []Command
undone []Command // 可选:用于 redo
}
func (i *CommandInvoker) Execute(cmd Command) {
cmd.Execute()
i.history = append(i.history, cmd)
i.undone = nil // 执行新命令后清空 redo 栈
}
func (i *CommandInvoker) Undo() {
if len(i.history) == 0 {
return
}
last := i.history[len(i.history)-1]
last.Undo()
i.history = i.history[:len(i.history)-1]
i.undone = append(i.undone, last)
}Undo() 只撤回最近一次 Execute(),符合常规交互直觉Undo() 即可,无需额外参数命令模式在 Go 中落地时容易忽略几点:
Undo() 中抛出 panic;建议返回 error 或静默失败(如文件已存在则跳过恢复)Undo() 也应同样支持 cancelhistory 最大长度(如只保留最近 100 条)基本上就这些。核心是把“做什么”和“谁来做”解耦,再让每个“做什么”自己知道怎么撤回——Go 的接口 + 结构体组合,足够干净地表达这个意图。
以上就是如何使用Golang实现命令模式撤销操作_使用Command Pattern支持撤销功能的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号