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模式的更多相关文章

  1. 设计模式:memento模式

    目的:在不破坏系统封装性的前提下,记录系统每一步的状态,可以做到状态回退和前进 方法: 定义一个数据类,保存所有相关数据 定义一个管理类,提供保存和恢复的接口 具体操作类调用管理类的保存和恢复接口 例 ...

  2. 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern)

    原文:乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 备忘录模式(Memento Pattern) 作者:webabc ...

  3. Java设计模式(15)备忘录模式(Memento模式)

    Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态. Memento模式相对也比较好理解,我们看下列代码: public class ...

  4. 设计模式之备忘录模式(Memento)

    备忘录模式(Memento) 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. Originator(发起人):负责创建一个备忘录 ...

  5. Memento模式(备忘录设计模式)

    Memento模式? 使用面向对象编程的方式实现撤销功能时,需要事先保存实例的相关状态信息.然后,在撤销时,还需要根据所保存的信息将实例恢复至原来的状态.这个时候你需要使用Memento设计模式.(以 ...

  6. C#设计模式:备忘录模式(Memento Pattern)

    一,C#设计模式:备忘录模式(Memento Pattern) 1.发起人角色(Originator):记录当前时刻的内部状态,负责创建和恢复备忘录数据.负责创建一个备忘录Memento,用以记录当前 ...

  7. 23种设计模式之备忘录模式(Memento)

    备忘录模式确保在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态.备忘录模式提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定 ...

  8. C++设计模式实现--备忘录(Memento)模式

    一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态.并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比較适用于功 ...

  9. 设计模式(十八)Memento模式

    在使用面向对象编程的方式实现撤销功能时,需要事先保存实例的相关状态信息.然后,在撤销时,还需要根据所保存的信息将实例恢复至原来的状态. 要想恢复实例,需要一个可以自由访问实例内部结构的权限.但是,如果 ...

随机推荐

  1. jquery -- checkbox选中无选中状态

    最近在工作中使用jquery操作checkbox,使用下面方法进行全选.反选: var ischecked=allCheckObj.is(':checked'); ischecked?checksOb ...

  2. 20160216.CCPP体系具体解释(0026天)

    程序片段(01):01.MemCpy.c 内容概要:内存拷贝 #include <stdio.h> #include <stdlib.h> #include <memor ...

  3. CentOS系统资源常用命令

    系统: # uname -a   # 查看内核/操作系统/CPU信息 # cat /etc/issue # cat /etc/redhat-release # 查看操作系统版本 # cat /proc ...

  4. Sqrt算法

    转自原文:http://www.cnblogs.com/pkuoliver/archive/2010/10/06/sotry-about-sqrt.html 一个Sqrt函数引发的血案 2010-10 ...

  5. Shell 获取Shell所在目录

    SHELL_PATH=$(cd ")";pwd) echo $SHELL_PATH

  6. sqlldr导入数据(以PostgreSql>>>Oracle为例)

    1.在目标数据库中创建表 1.1点击源表,复制创建语句 1.2 修改数据类型以匹配目标数据库,如: 字符串类型:character varying(20)>>>varchar2(20 ...

  7. jQuery-替换和删除元素

    1.replaceWith方法 用提供的内容替换集合中所有匹配的元素并且返回被替换元素的集合 参数类型说明: 1)普通字符串(可包含各种html标签) 2)jQuery对象 ①使用$函数创建的新元素( ...

  8. angular学习(十五)——Provider

    转载请写明来源地址:http://blog.csdn.net/lastsweetop/article/details/60966263 Provider简单介绍 每一个web应用都是由多个对象协作完毕 ...

  9. MySQL只有information_schema,test两个数据库

    一.现象 1.今天登上数据库,用 mysql -uroot -proot 登录(本人密码是root),出现: 2.然后尝试 无密码登录,竟然登录成功: 3.查看mysql中的数据库,发现只有两个系统表 ...

  10. isdigit()

    isdigit() 是字符串的一个方法,用来判断这个字符串是否是纯数字的字符串 In [1]: str = 'hello' In [2]: str.isdigit() Out[2]: False In ...