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. CentOS运行级别和开机过程

    linux运行级别: 1)0:关机 2)1:单用户 3)2:多用户状态没有网络服务 4)3:多用户状态有网络服务 5)4:系统未使用保留给用户 6)5:图形界面 7)6:系统重启 注:常用运行级别是3 ...

  2. CentOS命令top下你不一定懂的cpu显示信息

    在使用top命令的时候会看到这么一行: 里面的各个值分别是什么意思呢? 今天被问到这个问题,发现答的不是很清楚.果然啊,天天用最多的top命令都还没摸透...惭愧...于是就查了些资料: 官方解释 C ...

  3. js计算两个时间相差天数

     //两个时间相差天数 兼容firefox chrome    function datedifference(sDate1, sDate2) {    //sDate1和sDate2是2006-12 ...

  4. 如何强制关闭Tomcat

    用Myeclipse打开后启动Tomcat提示信息为:Address already in use: JVM_Bind:80 ,表示该地址和端口已经被占用显示已经打开了.但是关不掉他...所以只能去关 ...

  5. 【scrapy】相关

    http://www.cnblogs.com/mophee/archive/2009/03/12/1409562.html css选择器中的空格 http://www.crummy.com/softw ...

  6. meta标签整理

    meta指元素可提供有关页面的元信息(meta-information),比如针对搜索引擎和更新频度的描述和关键词.标签位于文档的头部,不包含任何内容. 标签的属性定义了与文档相关联的名称/值对. 一 ...

  7. [java] java 设计模式(2):抽象工厂模式(Abstract Factory)

    工厂方法模式有一个问题就是,类的创建依赖工厂类,也就是说,如果想要拓展程序,必须对工厂类进行修改,这违背了闭包原则,所以,从设计角度考虑,有一定的问题,如何解决?就用到抽象工厂模式,创建多个工厂类,这 ...

  8. Linux环境下$开头的相关变量的含义

    $0 这个程式的执行名字$n 这个程式的第n个参数值,n=1..9$* 这个程式的所有参数,此选项参数可超过9个.$# 这个程式的参数个数$$ 这个程式的PID(脚本运行的当前进程ID号)$! 执行上 ...

  9. VMware克隆虚拟机后网络不能正常使用的解决方法

    1.问题情况 在vmware中克隆一个虚拟机后,新的虚拟机网络无法使用,并用原操作系统中的网卡eth0在克隆出来的新系统中,网卡号变成了eth1,并且IP地址也丢失了,网络不可正常使用. 2.环境情况 ...

  10. PyQt4工具栏

    工具栏 菜单对程序中的所有命令进行分组防治,而工具栏则提供了快速执行最常用命令的方法. #!/usr/bin/python # -*- coding:utf-8 -*- import sys from ...