java备忘录模式应用场景_图解Java设计模式之备忘录模式
图解Java设计模式之备忘录模式
游戏角色状态恢复问题
游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态。
传统方案解决游戏角色恢复
传统的方式的问题分析
1)一个对象,就对应一个保存对象状态的对象,这样当我们游戏的对象很多时,不利于管理,开销很大。
2)传统的方式是简单的做备份,new出另外一个对象出来,再把需要备份的数据放到这个新对象,但这就暴露了对象内部的细节
备忘录模式基本介绍
1)备忘录模式(Memento Pattern)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
2)可以这里理解备忘录模式 :现实生活中的备忘录是用来记录某些要去做的事情,或者是记录已经达成的共同意见的事情,以防忘记。而在软件层面,备忘录模式有着相同的含义,备忘录对象主要用来记录一个对象某种状态,或者某些数据,当要做回退时,可以从备忘录对象里获取原来的数据进行恢复操作。
3)备忘录模式属于行为型模式。
备忘录模式原理类图
对原理类图的说明 :
1)originator :对象(需要保存状态的对象)
2)Memento :备忘录对象,负责保存好记录,即Originator内部状态
3)Caretaker :守护着对象,负责保存多个备忘录对象,使用集合管理,提高效率
4)说明 :如果希望保存多个originator对象的不同时间的状态,也可以,只需要HashMap
package com.example.demo.memento.theory;
public class Memento {
private String state;
public Memento(String state) {
super();
this.state = state;
}
public String getState() {
return state;
}
}
package com.example.demo.memento.theory;
import java.util.ArrayList;
import java.util.List;
public class Caretaker {
/*** 在list 集合中会有很多的备忘录对象*/
private List mementos = new ArrayList();
public void add(Memento memento) {
mementos.add(memento);
}
/*** 获取到第index个Originator 的 备忘录对象(即保存状态)* @param index* @return*/
public Memento get(int index) {
return mementos.get(index);
}
}
package com.example.demo.memento.theory;
public class Originator {
/*** 状态信息*/
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
// 编写一个方法,可以保存一个状态对象 Memento// 因此编写一个方法,返回Mementopublic Memento saveStateMemento() {
return new Memento(state);
}
public void getStateFromMemento(Memento memento) {
state = memento.getState();
}
}
package com.example.demo.memento.theory;
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stubOriginator originator = new Originator();
Caretaker caretaker = new Caretaker();
originator.setState(" 状态1 攻击力100 ");
// 保存当前状态caretaker.add(originator.saveStateMemento());
originator.setState(" 状态2 攻击力80 ");
// 保存当前状态caretaker.add(originator.saveStateMemento());
originator.setState(" 状态3 攻击力50 ");
// 保存当前状态caretaker.add(originator.saveStateMemento());
System.out.println(" 现在状态是 " + originator.getState());
// 希望得到状态1,将originator 恢复到状态1originator.getStateFromMemento(caretaker.get(0));
System.out.println(" 恢复状态 1");
System.out.println("当前的状态是 = " + originator.getState());
}
}
游戏角色恢复状态实例
1)应用实例要求
游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态
2)类图
package com.example.demo.memento.game;
public class Memento {
/**
* 攻击力
*/
private int vit;
/**
* 防御力
*/
private int def;
public Memento(int vit, int def) {
super();
this.vit = vit;
this.def = def;
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
package com.example.demo.memento.game;
import java.util.List;
import java.util.Map;
import javax.activation.MailcapCommandMap;
/**
* 守护者对象,保存游戏角色的状态
* @author zhaozhaohai
*
*/
public class Caretaker {
/**
* 如果只保存一次状态
*/
private Memento memento;
/**
* 对GameRole 保存多次状态
*/
private List list;
/**
* 对多个游戏角色保存多个状态
*/
private Map> rMap;
public Memento getMemento() {
return memento;
}
public void setMemento(Memento memento) {
this.memento = memento;
}
}
package com.example.demo.memento.game;
public class GameRole {
private int vit;
private int def;
/**
* 创建Memento,即根据当前的状态得到Memento
* @return
*/
public Memento createMemento() {
return new Memento(vit, def);
}
/**
* 从备忘录对象,恢复GameRole的状态
* @param memento
*/
public void recoverGameRoleFromMemento(Memento memento) {
this.vit = memento.getVit();
this.def = memento.getDef();
}
/**
* 显示当前游戏角色的状态
*/
public void display() {
System.out.println("游戏角色当前的攻击力 :" + this.vit + " 防御力 : " + this.def);
}
public int getVit() {
return vit;
}
public void setVit(int vit) {
this.vit = vit;
}
public int getDef() {
return def;
}
public void setDef(int def) {
this.def = def;
}
}
package com.example.demo.memento.game;
public class Client {
public static void main(String[] args) {
//创建游戏角色
GameRole gameRole = new GameRole();
gameRole.setVit(100);
gameRole.setDef(100);
System.out.println("和 boss 大战前的状态");
gameRole.display();
//把当前状态保存 caretaker
Caretaker caretaker = new Caretaker();
caretaker.setMemento(gameRole.createMemento());
System.out.println("和 boss 大战~~~");
gameRole.setDef(30);
gameRole.setVit(30);
gameRole.display();
System.out.println("大战后,使用备忘录对象恢复到站前");
gameRole.recoverGameRoleFromMemento(caretaker.getMemento());
System.out.println("恢复后的状态");
gameRole.display();
}
}
备忘录模式的注意事项和细节
1)给用户提供了一种可以恢复状态的机制,可以使用户能过比较方便地回到某个历史的状态。
2)实现了信息的封装,使得用户不需要关心状态的保存细节。
3)如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存,这个需要注意。
4)使用的应用场景 :1、后悔药;2、打游戏时的存档;3、Windows里的ctri + z。4、IE中的后退。4、数据库的事务管理。
5)为了节约内存,备忘录模式可以和原型模式陪着使用。
相关文章:

一文掌握常用的机器学习模型(文末福利)
AI 科技大本营按:本文节选自微软亚洲研究院机器学习研究团队刘铁岩、陈薇、王太峰、高飞合著的《分布式机器学习:算法、理论与实践》一书。为了让大家更好地理解分布式机器学习,AI科技大本营联合华章科技特别邀请到了本书的作者之一——微软亚…

MYSQL替换语句
update dede_art set titlereplace(title, <IMG border0 srcImages/hot.gif>,);update 表名(比如我案例中的dede_art) set 要修改字段名 replace (要修改字段名,被替换的特定字符,替换成的字符) SELECT * FROM supe_spaceitems where subject like %狐狸天空% update …

phpstudy+phpstorm+debug
文:phpstudyphpstormdebug 一、配置前说明: 1、phpStudy集成了XDebug扩展,所以不用单独下载XDebug。 2、打开XDebug扩展:其它选项菜单 > PHP扩展 > Xdebug 二、配置步骤: 1、phpStudy当前版本: 2、修改php.ini…

java 卖票问题_Java之多线程窗口卖票问题(Thread)
/**** 例子:创建三个窗口卖票,总票数为100张.使用继承Thread类的方式** 存在线程的安全问题,待解决。**/class Window extends Thread{private static int ticket 100;Overridepublic void run() {while(true){if(ticket > 0){System.out…

雷军深情告白:在我心里,武汉大学是全球最好的大学
武汉大学将在 11 月 29 迎来 125 周年校庆,作为杰出校友,小米创始人雷军参加了昨天举行的第五届校友珞珈论坛。现场,雷军对武大深情表白:“马云在几个场合说过,杭州师范大学在他心里是全球最好的大学,没有之…

java中抽象接口_一篇文章让你彻底理解java中抽象类和接口
相信大家都有这种感觉:抽象类与接口这两者有太多相似的地方,又有太多不同的地方。往往这二者可以让初学者摸不着头脑,无论是在实际编程的时候,还是在面试的时候,抽象类与接口都显得格外重要!希望看完这篇博…

linux proc
/proc文件系统下的多种文件提供的系统信息不是针对某个特定进程的,而是能够在整个系统范围的上下文中使用。可以使用的文件随系统配置的变化而变化。 /proc/cmdline 这个文件给出了内核启动的命令行。 /proc/cpuinfo 这个文件提供了有关系统CPU的多种信息。 /proc/d…

专访英特尔AIPG全球研究负责人Casimir Wierzynski:物理学、隐私和大脑将根本性塑造AI
出品| AI 科技大本营 在 11 月 14 日至 15 日在北京召开的英特尔人工智能大会(AIDC)上,英特尔人工智能产品事业部(AIPG)全球研究负责人 Casimir Wierzynski 发表了主题为《人工智能研究——物理学、隐私和大脑》的演讲…

微软OOXML申请国际文档标准已获通过 中国投反对票
51CTO.com北京时间3月28日中午通过消息灵通人士获悉,微软新一代文档标准OOXML已经获得国际标准化组织(ISO)的通过。中国依然投反对票。 ISO共有104个成员,其中包括41个技术能力强、参与标准化活动多的“P成员”。若微软文档标准想…

java中的匿名类方法覆盖_Java技巧:用匿名类来实现简化程序调试
Java技巧:用匿名类来实现简化程序调试在Java中,匿名类(Anonymous inner classes)多用来处理事件(event handle)。但其实,它们对于debug也很有帮助。本文将介绍如何利用匿名类来简化你的debug。我们该如何调试那些非自己源码的方法调用呢&…

记录第一次在egret项目中使用Puremvc
这几天跟着另一个前端在做一个小游戏,使用的是egret引擎和puremvc框架,这对于我来说还是个比较大的突破吧,特此记录下。 因为在此项目中真是的用到了mvc及面向对象编程,值得学习 记录第一次在egret项目中使用Puremvc: …

使用CSS制作圆角效果
Web2.0中,圆角效果是很常见的,以前都是用图片来模仿,现在直接用css就能实现,例子代码如下 Html代码: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> &…

知识图谱升温之势已现,不要错失下一个AI风口
近年来,随着大家对高级认知能力的积极探索,知识图谱因为表达能力强,扩展性好,并能兼顾人类认知与机器自动处理,引起了学术界、工业界以及政府部门的高度关注。 最先被大家熟知的应用领域应属搜索引擎,为了…

干货 | 谷歌BERT模型fine-tune终极实践教程
作者 | 奇点机智从11月初开始,Google Research就陆续开源了BERT的各个版本。Google此次开源的BERT是通过TensorFlow高级API—— tf.estimator进行封装(wrapper)的。因此对于不同数据集的适配,只需要修改代码中的processor部分,就能进行代码的…

java简介 ppt 精_《JAVA》5选择结构精篇课件.ppt
《JAVA》5选择结构精篇课件选 择 结 构 if 语句 if – else语句 Switch语句 块作用域语句又被称为复合语句,其格式为:用一对花括号将若干条语句括起来,目的是从语法上可以将多条语句解释成一条语句。 { int temp; temp a; a b; …

UPDATE STATISTICS 有何妙用?
txlicenhe 马可 一直没有关注它,今天刚学到的一招,还没彻底弄清楚。 情况是这样,有一个视图,用到了好几个表,其中一个表改了一些资料,在前台操作时总是超时过期(前台设置超时时间不长 60s&#…

js with用法
1)简要说明 with 语句可以方便地用来引用某个特定对象中已有的属性,但是不能用来给对象添加属性。要给对象创建新的属性,必须明确地引用该对象。 2)语法格式 with(object instance) { //代码块 } 有…

大数据时代,谁的眼神锁定你?
数据时代当前,欢迎来到楚门的世界。双十一余韵未歇,刚处理完一波售后及退件等“剁手后遗症”的各方人马也已经为再战双十二做好了准备。截至 12 日零点,天猫双十一成交额达 2135 亿元。与此同时,据国家邮政局监测数据显示…

Java类Demo中存在_Java中的数据类型转换
先来看一个题:Java类Demo中存在方法func0、func1、func2、func3和func4,请问该方法中,哪些是不合法的定义?( )public class Demo{float func0(){byte i1;return i;}float func1(){int i1;return;}float func2(){short i2;return i…

Exchange2000需要创建的3个SMTP服务实例
前一阵搞了邮件系统的安全加固,前面说的SA是一个方面,总觉得在SMTP上还有文章可做。分析一下公司的系统环境,SMTP的访问大概分这么三类:1、来自客户端的访问。2、来自公司业务系统服务器的访问。3、来自外部其它邮件服务器的访问。…
小程序门店自提功能开启,酷客多带你玩转O2O模式
目前小程序的发展已经如火如荼,不管是新型行业还是传统行业,都进军小程序领域,由此为广大消费者带来了方便与快捷,现在许多商家品牌将线上线下结合互动起来,推广门店自提的模式,酷客多小程序(ht…

“基因编辑婴儿”惹争议,你或许不知道机器学习在脱靶效应中的作用?
作者|琥珀出品| AI科技大本营又一次,计算机科学家和生物学者站在一起,对抗人类向内探索的挑战——用机器学习预测基因编辑 CRISPR 中的脱靶效应。今年年初,发表在《自然》生物工程杂志上的一篇论文描述了 Elevation 这项工具。该工具由微软研…

Flash Player漏洞利用Exploiting Flash Reliably
以下消息来自幻影论坛[Ph4nt0m]邮件组前两天推荐过Mark Dowd的Paper “Exploiting Flash Reliably”[url]http://hi.baidu.com/secway/blog/item/242655971275376855fb96d8.html[/url]学习了一下,很好很强大。为以后Flash Player漏洞的利用开辟了一条崭新崭新的道路…

java好用的hbase库_Hbase入库基于java
计划每周写一篇博客,督促自己快点学习,懒惰会让人上瘾,努力奋斗,不忘初心。某天,忽然来任务,要做hbse入库,之前自学过hbase,感觉挺简单的,网上搜了些model直接撸码&#…
linux(ubuntu)环境下安装及配置JDK
安装完IDEA之后遇到了问题,发现jdk安装完之后配置环境变量好困难,下面总结一下我的安装及配置方式: JDK下载链接:http://download.oracle.com/otn-pub/java/jdk/8u144-b01/090f390dda5b47b9b721c7dfaa008135/jdk-8u144-linux-x64.tar.gz 作者…

专访英特尔AIPG全球研究负责人Casimir Wierzynski:物理学、隐私和大脑将根本性塑造AI...
记者|琥珀出品| AI 科技大本营在 11 月 14 日至 15 日在北京召开的英特尔人工智能大会(AIDC)上,英特尔人工智能产品事业部(AIPG)全球研究负责人 Casimir Wierzynski 发表了主题为《人工智能研究——物理学、隐私和大脑…

flash php socket通信_php与flash as3 socket通信传送文件实现代码
前段时间在flashseer看到有人提到:可以通过socket方式传送swf文件,让用户无法获取到swf文件… 当时还没有出as3的反编译,所以对程序的保护没有在意.随着反编译程序的平民化,不希望别人看到源代码的朋友就比较着急…通过socket方式传送swf文件来避免泄漏源代码的思路(只适用as3)…

全线衰退:PC产业一枝孤秀
之三:全线衰退:PC产业一枝孤秀 在3C中,也许个人电脑(PC)产业算是当今中国最有希望的。中国的计算机工业号称已有50年历程,但成为民用产品的起始点应在30年前,与改革开放同时起步。1978年,国家成立了计算机工…

用Gogs在Windows上搭建Git服务
1.下载并安装Git,如有需求,请重启服务器让Path中的环境变量生效。2.下载并安装Gogs,请注意,在Windows中部署时,请下载MiniWinService(mws)版本。3.在MariaDB中创建一个命名为Gogs的数据库&#…

wamp安装多版本php,WampServer安装多个php版本
早期的WampServer安装多个版本php很简单,只需要单击php下的Get more...就行了,WampServer会自动导航到http://www.wampserver.com/addons_php.php下去安装php,但目前这种方式好像不行了,该页面找不到了,那么我们只能手…