上面两个例子,演示的都是保存一个状态(不是指一个成员,而是只存了最近一次状态),即一个检查点,但是实际应用中,状态往往不止存储一次,我们将上面储存状态的变量改为一个栈(或队列,主要看需求)即可。比如:BlackCaretaker中的private MementoIF memento;改为LinkedList<MementoIF> mementos 实现,保存的时候压栈(入队),恢复的时候出栈(出队)。具体实现都已经描述很清楚了,代码就不贴了(文章本来就太长了)。
针对上例,如果发起人和负责人我们并不介意他们必须是独立的,就可以把他们融合到一起,实现就会更佳简单,代码也简洁:
//自述历史备忘录public class MementoSelf { public static void main(String[] args) { OriginatorCaretaker originatorCaretaker = new OriginatorCaretaker();//发起人,同时为负责人 originatorCaretaker.changeState("stateOne"); //改变状态 IMemento memento = originatorCaretaker.createMemento(); //保存状态 originatorCaretaker.changeState("stateTwo"); //改变状态 originatorCaretaker.recoverMemento(memento); //恢复状态 }}intece IMemento {}//发起人兼负责人class OriginatorCaretaker { public String state; public void changeState(String state){ this.state = state; } //创造快照 public Memento createMemento(){ return new Memento(this); } //恢复状态 public void recoverMemento(IMemento memento){ Memento m = (Memento)memento; changeState(m.state); } //内部类实现备忘录 private class Memento implements IMemento{ private String state; private Memento(OriginatorCaretaker originatorCaretaker){ this.state = originatorCaretaker.state; } }}
上例演示仅保存一个检查点。下面再给出一个实际的例子:
这个程序为了保证功能相对完整,写作演示可能有点长了:
//文本编辑器public class TextEditor { public static void main(String[] args) { //使用这个文本编辑器 MyTextEditor editor = new MyTextEditor("这里是初始文本,可能为文件中读取的。"); System.out.println("开始修改文本:"); editor.append("添加文字1"); editor.delWords(); //删除最后一个// editor.delWords(2); //删除最后2个 这两个方法是没有问题的,这里避免控制台输出太多,取消这两次修改// editor.delWords(1,5); //删除前面5个 System.out.println("开始恢复:"); for(int i=0;i<10;i) editor.recoverMemento();//恢复大于实际修改的次数不会出错,只会将文本设为o初始化状态 System.out.println("开始重做:"); for(int i=0;i<10;i) editor.redo(); //重做大于实际恢复的次数不会出错,只会将文本设为最后状态 System.out.println("再次恢复:"); for(int i=0;i<10;i) editor.recoverMemento();//恢复大于实际修改的次数不会出错,只会将文本设为o初始化状态 System.out.println("再次重做:"); for(int i=0;i<10;i) editor.redo(); //重做大于实际恢复的次数不会出错,只会将文本设为最后状态 System.out.println("再次恢复:"); for(int i=0;i<10;i) editor.recoverMemento();//恢复大于实际修改的次数不会出错,只会将文本设为o初始化状态 editor.append("添加文字2"); System.out.println("再次重做:"); for(int i=0;i<10;i) editor.redo(); //重做大于实际恢复的次数不会出错,只会将文本设为最后状态 }}intece IMemento {}//发起人兼负责人class MyTextEditor { public StringBuffer text; private LinkedList<IMemento> mementos; //保存快照 private LinkedList<IMemento> undos; //保存撤销的操作 public MyTextEditor(){ this(""); } public MyTextEditor(String defaultStr){ text = new StringBuffer(defaultStr); mementos = new LinkedList<IMemento>(); undos = new LinkedList<IMemento>(); print(); } public void clearHistory(){ mementos.clear(); undos.clear(); } public void append(String appendStr){ if(appendStr==null||appendStr.length()==0) return; createMemento(); text.append(appendStr); print(); undos.clear(); } //删除最后一个 public void delWords(){ delWords(1); } //删除最后n个 public void delWords(int n){ if(n<1||n>text.length()) return; delWords(text.length()-n1,text.length()); } //删除中间start到end的字符,第一个文字为第一个(而不是0) public void delWords(int start,int end){ if(start<1 || end>text.length()1) return; createMemento(); text = text.delete(start-1, end); print(); } public void reset(String text){ this.text = new StringBuffer(text); } //新的快照 public void createMemento(){ mementos.push(new Memento(this)); } //恢复状态 public boolean recoverMemento(){ Memento memento = (Memento) mementos.poll(); if(memento==null) return false; undos.push(new Memento(this)); reset(memento.state); print(); return true; } //redo,redo的操作也可以恢复! public boolean redo(){ Memento memento = (Memento) undos.poll(); if(memento==null) return false; createMemento(); reset(memento.state); print(); return true; } //内部类实现备忘录 private class Memento implements IMemento{ private String state; private Memento(MyTextEditor editor){ this.state = editor.text.toString(); } } void print(){ System.out.println("当前文本:" text); }}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-33893-23.html
闯一下就不得了
收了多少钱
别人要摸你老婆的乳房