实现撤销操作的关键是将命令封装为对象并维护执行历史栈。通过定义包含execute()和undo()方法的命令接口,使每个操作可执行也可逆;利用栈结构存储已执行命令,支持多级撤销与重做;引入调用器Invoker统一管理命令的提交、撤销和重做,解耦控制逻辑;命令执行时保存必要状态信息,确保撤销时能准确恢复;控制栈的最大深度防止内存溢出。只要命令对象能可靠正向执行并反向撤销,配合完善的上下文记录与历史管理机制,即可构建稳定灵活的撤销框架。

实现支持撤销操作的命令模式框架,关键在于将操作封装为对象,并维护一个执行历史栈。通过统一接口定义命令的执行与回退行为,再由调用者控制命令的提交与撤销,即可构建灵活可靠的撤销机制。
定义命令接口
所有可执行且可撤销的操作都应实现统一的命令接口。该接口包含两个核心方法:执行和撤销。
- execute():执行具体业务逻辑,如修改数据、移动元素等
- undo():逆向操作,恢复 execute 带来的状态变化
例如编辑文本的“插入文字”命令,execute 插入内容,undo 则删除对应文字并还原光标位置。
管理命令的历史记录
使用栈结构保存已执行的命令,是实现多级撤销的基础。同时可维护另一个栈用于重做(redo)。
- 每执行一个命令,将其推入“已执行栈”
- 撤销时从栈顶取出命令调用 undo(),并移入“可重做栈”
- 重做则反向操作,调用 redo 或再次 execute
注意控制栈的大小,避免内存溢出,可通过设置最大步数自动清理旧记录。
封装命令调用器
引入调用器(Invoker)对象统一管理命令的执行流程,解耦界面操作与具体逻辑。
UQCMS云商是一款B2B2C电子商务软件 ,非常适合初创的创业者,个人及中小型企业。程序采用PHP+MYSQL,模板采用smarty模板,二次开发,简单方便,无需学习其他框架就可以自行模板设计。永久免费使用,操作简单,安全稳定。支持PC+WAP+微信三种浏览方式,支持微信公众号。
调用器提供 public 方法如 do(command)、undo()、redo(),内部处理栈操作与边界判断(如栈为空时禁用撤销)。
这样上层代码只需关注生成合适的命令实例,无需了解执行细节或状态管理。
确保状态一致性
命令必须准确记录执行前的状态,或能安全推导出逆操作。常见做法包括:
- 在 execute 中备份受影响的数据副本
- 存储操作前的关键参数(如原始坐标、值)
- 使用事务日志方式记录变更,便于回滚
避免在 undo 中重复业务判断,应依赖 execute 时保存的上下文信息直接还原。
基本上就这些。只要命令对象能可靠地正向执行和反向撤销,配合良好的历史管理,就能构建出稳定可用的撤销框架。









