设计模式:利用Command模式实现无限次数的Undo/Redo功能

原创 2002年05月20日 10:55:00

几乎现在所有的文档式应用程序中,都提供了恢复/撤消功能,如Word,Excel,还有我们的写Java程序用的JBuilder。


在早期,许多的应用程序还只能提供单一的Undo/Redo,自进入90年代以来,随着OOP及Design Pattern的流行,实现无限次数的Undo/Redo编辑功能已不是难事。


每一个编辑动作我们可以把它当成一个命令,如cut,del等,在做每一个编辑动作前,我们先要保存旧的数据,以便于undo它。我们为这些编辑命令设计了如下一个通用接口:
public Interface Command
{


    public void execute(); 


    public void undo();


}
其中execute用来执行命令,undo用来恢复(undo).


接下来实现这个接口,先来实现Cut命令:
public class CutCommand implements Command
{


    public void execute()
    {
        /* 备份旧数据 */
        /* 剪切 */


    }


    public void undo()
    {
         /*  还原成备份的数据  */
    }


}


再来实现一个Delete命令:
public class DeleteCommand implements Command
{


    public void execute()
    {
        /* 备份旧数据 */
        /* 删除 */


    }


    public void undo()
    {
         /*  还原成备份的数据  */
    }


}


OK,我们就只列出了cut和del两个命令,其它的命令相似的写法.


这样的话我们每做一个编辑动作,就执行一个相应的command.接下来我们要考虑如何将这些执行过的命令保存下来,以实现undo/redo. 我们再设计一个CommandManager:
public Interface CommandManager
{
    public void storeCommand(Command cmd);
    public void clearAllCommand();
    public void undo();
    public void redo();
}
再来实现一个CommandManager, 我们称作CommandHistoryManager:
public class CommandHistoryManager implements CommandManager
{
 Vector undoList=new Vector();
 Vector redoList=new Vector();
 
 
 public void storeCommand(Command cmd)
 {
  undoList.add(cmd);
 }
 public void clearAllCommand()
 {
  undoList.clear();
  redoList.clear();
 }
 public void undo()
 {
        if ( undoList.size() <= 0 ) return;
        Command cmd = ((Command)(undoList.get(undoList.size()-1)));
        cmd.undo();
        undoList.remove(cmd);
        redoList.add(cmd);
 }
 public void redo()
 {
        if ( redoList.size() <= 0 ) return;
        Command cmd = ((Command)(redoList.get(redoList.size()-1)));
        cmd.execute();
        redoList.remove(cmd);
        undoList.add(cmd);
  
 }
 
}
通过storeCommand()方法,每次执行的command就可以保存到undoList中,假设再在我们在程序中放置了两个按钮,一个undo,一个redo.按下undo按钮,就执行CommandHistoryManager的undo()方法,undo()方法会调用undoList中保存的最后一个command的undo()方法,并将这个command再放到redoList中,最后从undoList中删除这个命令。这时如果再按redo按钮,它会调用CommandHistoryManager中的redo()方法。redo()方法会调用redoList中保存的最后一个command的execute()方法,并将这个command又存回到undoList中。这样就实现了无限次数的undo/redo功能。

 

理解数据库中的undo日志、redo日志、检查点

数据库存放数据的文件,本文称其为data file。 数据库的内容在内存里是有缓存的,这里命名为db buffer。某次操作,我们取了数据库某表格中的数据,这个数据会在内存中缓存一些时间。对这个数据...
  • kobejayandy
  • kobejayandy
  • 2016年03月14日 13:34
  • 6947

redo与undo

redo(重做信息)是Oracle在在线(或归档)重做日志文件中记录的信息,万一出现失败时可以利用这些数据来“重放”(或重做)事务。 Oracle维护着两类重做日志文件:在线(online)重做日志文...
  • wildin
  • wildin
  • 2010年08月28日 10:19
  • 13183

多步Undo_Redo的实现

  • 2012年03月01日 17:54
  • 43KB
  • 下载

Redo Undo 的三种实现

原文地址 Redo Undo 的三种实现 Published on 2012 年 6 月 26 日, by chenxin in 未分类. 在开发程序时,经常需要...
  • xue_jiang_han2013
  • xue_jiang_han2013
  • 2014年05月22日 15:44
  • 1456

Oracle 中UNDO与REDO的区别详解

一 为了更清楚的看出2者区别,请看下表:                                               UNDO                            ...
  • IndexMan
  • IndexMan
  • 2014年05月17日 15:20
  • 9300

Redo 和Undo的区别和联系 详细解释

Redo和Undo Redo及其作用Undo及其作用Redo与Undo的关系提交和回滚处理基于LogMiner的日志分析   1 1.1  Redo及其作用   1.1...
  • u011436548
  • u011436548
  • 2013年11月08日 16:57
  • 3775

Undo和Redo机制

Redo 和 Undo 机制Andy Liu2007-10-11        提到应用程序的Redo和Undo机制,大家马上会想到Command模式,的确任何一个软件在响应用户命令和操作时,都是用了...
  • Windbell07
  • Windbell07
  • 2007年10月11日 17:22
  • 1970

手把手教你写Undo、Redo程序

 手把手教你写Undo、Redo程序     Undo、Redo操作是很多具体编辑功能的软件所不能缺少的。最典型两种类型就是文本编辑和图像编辑软件。然而它的实现在某种程度上来说也不是很简单。我也废话少...
  • laiyiling
  • laiyiling
  • 2006年10月20日 13:39
  • 10589

undo log与redo log原理分析

数据库通常借助日志来实现事务,常见的有undo log、redo log,undo/redo log都能保证事务特性,这里主要是原子性和持久性,即事务相关的操作,要么全做,要么不做,并且修改的数据能得...
  • xuanxuan_good
  • xuanxuan_good
  • 2017年01月14日 15:59
  • 504

undo redo 实现感想

  • 2010年05月26日 23:49
  • 215KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:设计模式:利用Command模式实现无限次数的Undo/Redo功能
举报原因:
原因补充:

(最多只允许输入30个字)