设计模式之备忘录(纪念品)模式(Memento)
备忘录模式的个人理解:
使用Memento模式的好处在于可以将以前曾经拥有的状态再次获得。相当于游戏中的存档一样,我们经常在打Boss的时候会先存档,然后再打Boss,防止我们在挑战Boss的过程中牺牲了,然后前面关卡上玩的金币呀,经验呀,装备呀什么的都没有了。所以我们可以在挑战Boss失败的时候,重新读档,再次开打。这个我经常用在仙剑的游戏中。。。备忘录模式简单的一句话就是:事先把数据存档,将来重新读档。备忘录模式中主要的对象有:Originator,Memento,CareTaker。首先,作为一个Originator,它必须要有自己的数据域,以便被我们的Memento来复制存储。Memento需要有的是跟Originator相匹配的数据域,不然拿什么来复制Originator的数据呢?最后是一个管理Memento的CareTaker,管理生成的Memento对象。这里我模拟了一个关于我们word下面文字输入的撤销操作,就是将编辑操作进行撤销,还原到某个点上。思路清晰,上代码:
//原始的主体发起人。 public class Originator_Text { private String txt; private int countNum; public Originator_Text() { txt = ""; countNum = 0; } public void printData() { System.out.println("当前正在编辑的文字:" + txt + " 字数:" + countNum); } // 编辑文字的过程中,并复制到Memento对象中,生成返回Memento的存储对象 public Memento edit_txt(String str) { System.out.println("输入文字: " + str); txt = str; countNum = txt.length(); // 编辑文字,并将其保存到Memento对象中 return saveToMemento(); } private Memento saveToMemento() { // 新建Memento对象,用来存储发起人的数据域 Memento m = new Memento(txt, countNum); return m; } public void restoreMemento(Memento m) { txt = m.getText(); countNum = m.getNum(); } }
public class Memento { private String m_txt; private int m_countNum; public Memento() { } // 备忘录Memento对发起人传过来的数据进行复制存储 public Memento(String txt, int num) { m_txt = txt; m_countNum = num; } public String getText() { return m_txt; } public int getNum() { return m_countNum; } }
import java.util.Stack; //Memento备忘录管理者,只负责管理Memento对象,从来不关心Memento里面的具体内容。 public class CareTaker { Stack<Memento> stack = new Stack<Memento>(); public void saveMemento(Memento m) { stack.push(m); } public Memento retrieveMemento() { if (!stack.isEmpty()) return stack.pop(); return null; } }
测试类:这里我们首先输入几组数据,然后进行撤销操作,输入数据的过程就涉及关于对Memento的创建,对Originator的数据复制。在撤销操作中,就涉及如何将Memento中的数据恢复到Originator上面。
public class Main { public static void main(String[] args) { // 创建发起人、备忘录管理员 Originator_Text ot = new Originator_Text(); CareTaker ct = new CareTaker(); // 备忘录管理员存储Memento对象 ct.saveMemento(ot.edit_txt("vokie")); ct.saveMemento(ot.edit_txt("sina")); ot.edit_txt("google"); ot.printData(); System.out.println("\n撤销操作"); // 撤销一次,将发起人的数据进行重新装载到以前版本。 ot.restoreMemento(ct.retrieveMemento()); // 打印当前的ot正在编辑的数据 ot.printData(); System.out.println("\n撤销操作"); // 撤销一次,将发起人的数据进行重新装载到以前版本。 ot.restoreMemento(ct.retrieveMemento()); // 打印当前的ot正在编辑的数据 ot.printData(); } }
运行结果:
输入文字: vokie 输入文字: sina 输入文字: google 当前正在编辑的文字:google 字数:6 撤销操作 当前正在编辑的文字:sina 字数:4 撤销操作 当前正在编辑的文字:vokie 字数:5
项目宏观的看一下,也就是在操作栈,不过弹出的数据Memento进行了一点操作,比如复制数据,恢复数据等。我们看出Memento类给人的感觉有点像是一个容器,提供了一定的接口给外界存入数据(复制存档),导出数据(撤销恢复)。
项目下载链接:http://www.kuaipan.cn/file/id_132802506211221449.htm?source=1