Command设计模式应用时的几个问题

在文档/视图设计时需要考虑Undo/Redo,而最好的方法是使用Command设计模式实现。在实际应用Command模式实现Undo/Redo时遇到了一些问题。在开始的时候,逻辑非常混乱,不过经过讨论之后,问题开始清晰,实际上良好的设计使得实现的复杂性大大降低。
1. 时间戳的问题。
Command都有时间戳,文档是否修改正是通过比较文档的时间戳和当前Command的时间戳是否相等。但是Undo到Command队列头部的时候,再Undo的话,时间戳怎样设置,我原来想过当前命令时间戳应该回到0,但是这样并不合逻辑。如果到了一种状态:队列为空,而且文档时间戳不为0,这时候执行了一个Command,再Undo,显然命令时间戳不应该回到0。这时候可以考虑队列的第一个元素作为保留的元素,队列的实际Command从第二个元素开始,Undo到这个Command之后,再Undo将回到第一个保留的Command,这样队列头部元素的操作与其它元素将没有区别。回想到stl::list的实现,当list为empty时并不是真正的空,还是有一个元素的,这个元素实际上就是list::end()指向的元素。
2. Command的合并。
多个相同的Command可以合并,这样Undo的时候将全部Undo这些Command,这在Microsoft Word中表现得最显著了。但是这里有一个合并的条件问题。我原来考虑通过时间、复杂性等条件设置。例如:在一定时间范围内,对同一文档两个相同的命令可以合并。而考虑到Doc/View的关系,Doc新增加命令了,View的Command就不能再合并了。此外,Undo之后Command也不应该合并。这里的逻辑异常复杂,在设计的时候既要考虑实现这些逻辑,还要考虑以后增加新的逻辑的扩展性。但是实际上,时间戳由系统签发,任何两个不同命令的时间戳都不相等,这时候如果考虑最后一个运行的命令的时间戳是系统签发的最后一个时间戳,那么命令就可以合并,是不是就一切逻辑都涵盖了呢?而且还很人性化呢!

关于Undo/Redo时间戳的问题,还有很多,比如Command合并时是否应该申请新的时间戳?文档保存以后似乎不应该合并命令。待设计完成之后,一定要全面总结一下。

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页