设计模式之——Memento模式
Memento模式即快照模式,就是在某一时刻,设定一个状态,在后面随时可以返回到当前状态的模式。
我们拿一个闯关游戏作为举例,一共有十关,每闯一关,玩家所持金额增加一百,而闯关失败就扣一百。初始时,给玩家一百块作为闯关资金,如果十关全部闯玩,并且玩家手中金额不小于0,则胜利,当玩家所持金额小于0,则视为闯关失败,直接退出。
下面看案例代码,有一个玩家类
- gamer
package site.wangxin520.gof.memento.demo.game; import java.util.Random; /**
* 游戏的类
* @author wangXgnaw
*
*/
public class Gamer { /**
* 玩家所持有的金钱
*/
private int money;
private Random random = new Random(); /**
* 创建玩家,设置初始化money
* @param money
*/
public Gamer(int money) {
this.money = money;
} /**
* 获取玩家当前所持有的金钱
* @return
*/
public int getMoney() {
return money;
} /**
* 玩游戏的方法
*/
public void play(){ //要么闯关成功
if(random.nextBoolean()){
System.out.println("闯关成功,加一百块");
this.money+=100;
}else{
System.out.println("闯关失败,扣两百块");
this.money-=200;
} } @Override
public String toString() {
return "玩家当前有现金: [money=" + money + "]";
} }
- test测试类
package site.wangxin520.gof.memento.demo; import site.wangxin520.gof.memento.demo.game.Gamer; /**
* 快照模式的一个测试类
* @author wangXgnaw
*
*/
public class Test { public static void main(String[] args) {
Gamer gamer = new Gamer(100); System.out.println("初始时候,玩家状态为:"+gamer); //玩十局游戏
for (int i = 0; i < 10; i++) { gamer.play(); System.out.println("第"+(i+1)+"局的时候,玩家状态为:"+gamer); //判断游戏结束
if(gamer.getMoney()<0){
System.out.println("玩家失败");
break;
}
}
System.out.println(); } }
- 此时运行后控制台为:

玩家玩到第三局的时候,就失败了。同样多测试几次后也类似,少有的一路顺风直到最后的。可见,这个游戏是有难度的,那么我们怎么去百分百的成功呢。
假设我们设置,在游戏开始前,设置一个快照,保存游戏进度,当游戏开始后,赢了的话,就更新进度,输了的话,就重新开始当前的关卡。
- 我们设置了一个快照类,用于保存进度的
package site.wangxin520.gof.memento.demo.game; /**
* 游戏的快照的类,当需要爆粗的时候,保存一下进度,用于快速恢复!
* @author wangXgnaw
*
*/
public class Memento { //保存游戏里面的钱
private int money; /**
* 构造函数,创建一个快照
* 限定为只能本包中调用
*/
Memento(int money) {
this.money=money;
} /**
* 获取快照保存的钱,这里方法的权限为本包中
* @return
*/
int getMoney() {
return money;
}
}
- 修改一下玩家类
package site.wangxin520.gof.memento.demo.game; import java.util.Random; /**
* 游戏的类
* @author wangXgnaw
*
*/
public class Gamer { /**
* 玩家所持有的金钱
*/
private int money;
private Random random = new Random(); /**
* 创建玩家,设置初始化money
* @param money
*/
public Gamer(int money) {
this.money = money;
} /**
* 获取玩家当前所持有的金钱
* @return
*/
public int getMoney() {
return money;
} /**
* 玩游戏的方法
*/
public void play(){ //要么闯关成功
if(random.nextBoolean()){
System.out.println("闯关成功,加一百块");
this.money+=100;
}else{
System.out.println("闯关失败,扣两百块");
this.money-=200;
} } /**
* 创建快照,当前的所持的金额
* @return Memento 返回一个快照
*/
public Memento createMemento(){
return new Memento(this.money);
} /**
* 回退到快照
* @param memento
*/
public void restoreMemento(Memento memento){
this.money=memento.getMoney();
} /**
* 查看快照里面的钱
* @return
*/
public int getMementoState(Memento memento){
return memento.getMoney();
} @Override
public String toString() {
return "玩家当前有现金: [money=" + money + "]";
} }
- 测试类也修改了一下,当成功,就更新进度,当不成功,就回退
package site.wangxin520.gof.memento.demo; import site.wangxin520.gof.memento.demo.game.Gamer;
import site.wangxin520.gof.memento.demo.game.Memento; /**
* 快照模式的一个测试类
* @author wangXgnaw
*
*/
public class Test { public static void main(String[] args) {
Gamer gamer = new Gamer(100); System.out.println("初始时候,玩家状态为:"+gamer); //设置一个快照
Memento memento=gamer.createMemento(); //玩十局游戏
for (int i = 0; i < 10; i++) { gamer.play(); //当钱减少后,就说明了玩家本局闯关失败,那么就回退回去
if(gamer.getMoney()<gamer.getMementoState(memento)){
gamer.restoreMemento(memento);
//并且,本局重新来过!
i--;
}else{
//本次闯关成功,更新快照
memento=gamer.createMemento();
} System.out.println("第"+(i+1)+"局的时候,玩家状态为:"+gamer); //判断游戏结束
if(gamer.getMoney()<0){
System.out.println("玩家失败");
break;
}
}
System.out.println(); } }
- 此时控制台输出就变成了:

当闯关失败时候,就恢复到快照,成功就继续闯关。这样一来,基本上就是百试不爽的,次次成功了。哈哈哈!!!
设计模式之——Memento模式的更多相关文章
- 设计模式:memento模式
目的:在不破坏系统封装性的前提下,记录系统每一步的状态,可以做到状态回退和前进 方法: 定义一个数据类,保存所有相关数据 定义一个管理类,提供保存和恢复的接口 具体操作类调用管理类的保存和恢复接口 例 ...
- 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)
原文:乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) 作者:webabc ...
- Java设计模式(15)备忘录模式(Memento模式)
Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...
- 设计模式之备忘录模式(Memento)
备忘录模式(Memento) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. Originator(发起人):负责创建一个备忘录 ...
- Memento模式(备忘录设计模式)
Memento模式? 使用面向对象编程的方式实现撤销功能时,需要事先保存实例的相关状态信息.然后,在撤销时,还需要根据所保存的信息将实例恢复至原来的状态.这个时候你需要使用Memento设计模式.(以 ...
- C#设计模式:备忘录模式(Memento Pattern)
一,C#设计模式:备忘录模式(Memento Pattern) 1.发起人角色(Originator):记录当前时刻的内部状态,负责创建和恢复备忘录数据.负责创建一个备忘录Memento,用以记录当前 ...
- 23种设计模式之备忘录模式(Memento)
备忘录模式确保在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态.备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定 ...
- C++设计模式实现--备忘录(Memento)模式
一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态.并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比較适用于功 ...
- 设计模式(十八)Memento模式
在使用面向对象编程的方式实现撤销功能时,需要事先保存实例的相关状态信息.然后,在撤销时,还需要根据所保存的信息将实例恢复至原来的状态. 要想恢复实例,需要一个可以自由访问实例内部结构的权限.但是,如果 ...
随机推荐
- (转)学习linux的几本书
成为一名精通 Linux 程序设计的高级程序员一直是不少朋友孜孜以求的目标.根据中华英才网统计数据,北京地区 Linux 程序员月薪平均为 Windows 程序员的 1.8 倍.Java 程序员的 2 ...
- sourcetree管理git
下载地址: https://www.sourcetreeapp.com/ 跳过注册: 到注册登录页面打开文件目录%LocalAppData%\Atlassian\SourceTree\ 会发现有个文件 ...
- storm深入研究
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:He Ransom链接:http://www.zhihu.com/question/23441639/answer/28075 ...
- 编辑框添加灰色提示字(html+VC)
Html中添加灰色提示字,使用属性placeholder即可! <input type="text" placeholder="要显示的文字"> 但 ...
- [java] java 设计模式(2):抽象工厂模式(Abstract Factory)
工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这 ...
- A complete example using RAISE_APPLICATION_ERROR : raise_application_error
from:http://www.java2s.com/Tutorial/Oracle/0480__PL-SQL-Programming/AcompleteexampleusingRAISEAPPLIC ...
- ionic 下拉刷新,上拉加载更多
1)下拉刷新用的是 ion-refresher,使用示例如下: <ion-refresher pulling-text="Pull to refresh..." on-ref ...
- PHP之语句
前面的话 任何 PHP 脚本都是由一系列语句构成的.一条语句可以是一个赋值语句,一个函数调用,一个循环,一个条件语句或者甚至是一个什么也不做的语句(空语句).语句通常以分号结束.此外,还可以用花括号将 ...
- poj_1475 BFS+BFS
题目大意 推箱子游戏的基本玩法,求将箱子推到目的地的推动次数最少(并不是人移动总次数)的人移动路径. 题目分析 求最短路径的搜索问题,使用BFS.注意题目求的是 推动次数最少,因此将箱子移动作为状态, ...
- JavaBean与Map<String,Object>相互转换
一.为什么要实现javaBean与Map<String,Object>相互转换 Spring中的BaseCommandController对象可以将传递过来的参数封装到一个JavaBean ...