电话
400 9058 355
Go中命令模式核心是将操作转为函数值,用type Command func()最轻量;需撤销时返回执行/撤销函数对,共享闭包状态;批量执行须逆序回滚,仅联动多步骤操作才值得封装。
Go 里命令模式不是用来“模拟 Java 风格接口继承”的,而是把操作变成值——能存、能传、能延迟调用、还能自带撤销逻辑。用对了很轻量,用错了反而多写一堆 struct 和 interface。
func() 类型代替 Command 接口最省事90% 的场景根本不需要定义 type Command interface { Execute() }。Go 的函数是一等公民,直接用类型别名更自然、无抽象开销、闭包还能捕获上下文:
type Command func() 就够了;需要返回值或错误时,改用 func() error
saveCmd := func() error { return db.Save(user) }

saveCmd()
Undo() 方法Go 没有虚函数机制,Undo() 方法无法被统一调度,除非你手动维护历史栈并显式调用。更 Go 的做法是:命令创建时就返回一对函数——执行和撤销,状态由闭包捕获:
func NewCounterIncCommand(counter *int) (func(), func()) {
oldValue := *counter
execute := func() { *counter++ }
undo := func() { *counter = oldValue }
return execute, undo
}
oldValue),不依赖外部状态管理器undo 必须幂等且考虑失败路径,比如 os.Remove 失败不应 panic,而应返回 errorexecute 和 undo 字段undo
用 []func() error 存命令队列很简单,但出错时回滚逻辑容易写错:
undo 函数defer 或 recover,因为部分命令可能已生效,需显式补偿RunCommands(commands []func() error) error,内部自动记录成功索引,出错后按逆序调用对应 undo
undo 应优先做清理,而非业务语义回退(那是上层逻辑的事)真正难的不是怎么封装命令,而是判断哪些操作值得封装——比如 HTTP handler 中的一次数据库更新,通常没必要做成命令;但用户触发的“发布文章+发通知+更新统计”这一组联动操作,就适合用命令队列+统一错误处理+可选回滚来组织。状态捕获是否完整、undo 是否可重入、命令生命周期是否清晰,这些细节比结构体长得好不好看重要得多。
邮箱:8955556@qq.com
Q Q:8955556
本文详解如何将Go官方present工具(用于生成HTML5...
PySNMP在不同版本中对SNMP错误状态(errorSta...
time.Sleep仅阻塞当前goroutine,其他gor...
PHPfopen()创建含特殊符号的文件名失败主因是操作系统...
WooCommerce中通过代码为分组产品动态聚合子商品的属...
io.ReadFull返回io.ErrUnexpectedE...
本文详解Yii2中控制器向视图传递ActiveRecord数...
本文详解为何通过wp_set_object_terms()为...
Pytest中使用@mock.patch类装饰器会导致补丁泄...
带缓冲的channel是并发安全的FIFO队列;make(c...