0

0

如何在Golang中构建命令模式_Golang命令模式操作封装示例

P粉602998670

P粉602998670

发布时间:2026-01-26 13:43:42

|

832人浏览过

|

来源于php中文网

原创

命令模式在Go中核心是封装可撤销的执行单元,应使用结构体承载状态和上下文,明确依赖与错误处理,避免硬套接口,按需实现Undo而非强制统一。

如何在golang中构建命令模式_golang命令模式操作封装示例

命令模式的核心不是接口,而是可撤销的执行单元

Go 语言没有传统面向对象的抽象类或虚函数,所以硬套 UML 类图里的 Command 接口 + execute()/undo() 方法容易跑偏。真正关键的是:把「一个操作」封装成能延迟调用、能携带上下文、能统一管理生命周期的值。Go 里最自然的载体就是函数类型和结构体组合。

用 struct 封装命令比纯函数更实用

纯函数(如 func())无法自带状态,而真实命令往往需要参数、依赖、甚至回滚所需的数据快照。用结构体承载命令逻辑,既清晰又可控。

  • Execute()Undo() 方法必须接收明确的上下文(比如 *AppDB),不能隐式依赖全局变量
  • 命令实例应在创建时捕获必要参数(如 ID、原始值),避免执行时再去查——否则 undo 可能失败
  • 如果命令涉及 IO 或可能失败,Execute() 应返回 errorUndo() 同理,且不应 panic
type DeleteUserCommand struct {
    UserID int
    Name   string // 执行前缓存,用于 undo 恢复
    DB     *sql.DB
}

func (c *DeleteUserCommand) Execute() error {
    _, err := c.DB.Exec("DELETE FROM users WHERE id = ?", c.UserID)
    return err
}

func (c *DeleteUserCommand) Undo() error {
    _, err := c.DB.Exec("INSERT INTO users(id, name) VALUES (?, ?)", c.UserID, c.Name)
    return err
}

命令队列要区分「执行」和「撤销」的顺序逻辑

典型误区是把命令堆进 slice 然后逆序调 Undo() —— 这只适用于线性、无分支的操作流。实际中更常见的是:用户执行 A → B → C,然后撤销 C,再执行 D,此时历史不该丢弃 A/B,但也不能让 D 的 undo 插在 C 前面。

  • 推荐用[]Command)只记录已执行且**未被覆盖**的命令
  • 每次新命令执行前,先清空栈顶所有已被「跳过」的 undo 项(即实现类似 Photoshop 的“历史画笔”行为)
  • 撤销操作本质是 pop + Undo(),而非遍历整个历史

不要给每个命令都加 undo,优先保证 execute 的幂等与可测

很多业务场景(如发通知、写日志、调第三方 API)根本不可逆。强行设计 Undo() 会引入额外状态管理成本,还可能掩盖真正的问题。

RecoveryFox AI
RecoveryFox AI

AI驱动的数据恢复、文件恢复工具

下载

立即学习go语言免费学习笔记(深入)”;

  • 对无法 undo 的命令,Undo() 可返回 errors.New("not supported"),调用方需处理该错误
  • 更务实的做法是:用事件溯源(event sourcing)替代命令模式——把所有变更记为不可变事件,重放即恢复状态
  • 测试时重点验证 Execute() 是否按预期修改了状态,而不是纠结 undo 是否“完美”

命令模式在 Go 里不是炫技工具,它是当你需要精确控制操作生命周期、支持重做/撤销、或解耦触发与执行时机时的务实选择。别先定义接口,先想清楚:这个操作要传什么?在哪执行?失败了怎么收场?undo 是刚需,还是自我感动?

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

180

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

228

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

341

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

209

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

393

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

220

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

192

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

335

2025.06.17

npd人格什么意思 npd人格有什么特征
npd人格什么意思 npd人格有什么特征

NPD(Narcissistic Personality Disorder)即自恋型人格障碍,是一种心理健康问题,特点是极度夸大自我重要性、需要过度赞美与关注,同时极度缺乏共情能力,背后常掩藏着低自尊和不安全感,影响人际关系、工作和生活,通常在青少年时期开始显现,需由专业人士诊断。

1

2026.01.26

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 4.2万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号