设计模式之备忘录(纪念品)模式(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("
撤销操作");
		// 撤销一次,将发起人的数据进行重新装载到以前版本。
		ot.restoreMemento(ct.retrieveMemento());
		// 打印当前的ot正在编辑的数据
		ot.printData();

		System.out.println("
撤销操作");
		// 撤销一次,将发起人的数据进行重新装载到以前版本。
		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

原文地址:https://www.cnblogs.com/vokie/p/3602075.html