zoukankan      html  css  js  c++  java
  • 设计模式之备忘录(纪念品)模式(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

  • 相关阅读:
    javascript进阶,从表达式到引用类型,变量监听
    nodejs和es6,es5等关系
    前后端分离工程带来的问题
    vue难点解析
    angular框架及其UI使用
    Javascript入门和TypeScrip入门
    从熟悉项目到开发项目
    昌平某公司入职一周感想
    css和前端UI框架设计ElementUI
    2020新征程
  • 原文地址:https://www.cnblogs.com/vokie/p/3602075.html
Copyright © 2011-2022 走看看