设计模式之——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模式
在使用面向对象编程的方式实现撤销功能时,需要事先保存实例的相关状态信息.然后,在撤销时,还需要根据所保存的信息将实例恢复至原来的状态. 要想恢复实例,需要一个可以自由访问实例内部结构的权限.但是,如果 ...
随机推荐
- 常用CSS缩写语法总结(转)
使用缩写可以帮助减少你CSS文件的大小,更加容易阅读.css缩写的主要规则如下: 颜色 16进制的色彩值,如果每两位的值相同,可以缩写一半,例如:#000000可以缩写为#000;#336699可以缩 ...
- php -- 取日期
1.获取当前时间方法date()很简单,这就是获取时间的方法, 格式为:date($format, $timestamp), format为格式 - 必需 timestamp为时间戳–可填参数. 比如 ...
- 【Java面试题】26 多线程有几种实现方法?同步有几种实现方法? 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法?
问题一:多线程有几种实现方法?同步有几种实现方法? 多线程有两种实现方法,分别是继承Thread类与实现Runnable接口 同步的实现方面有两种,分别是synchronized,wait与not ...
- php中获取网站访客来源的关键词方法
php中获取网站访客来源的关键词方法,收集了 <?php class keyword{ public function getKeyword($referer){ if(strpos($refe ...
- db2 over()
说起 DB2 在线分析处理,可以用很好很强大来形容.这项功能特别适用于各种统计查询,这些查询用通常的SQL很难实现,或者根本就无发实现.首先,我们从一个简单的例子开始,来一步一步揭开它神秘的面纱,请看 ...
- 桥接模式(bridge pattern)-------结构型模式
桥接模式是一种对象结构型模式,其将抽象部分和它的实现部分分离,使它们都可以独立的变化,又称为柄体(Handle and Body)模式或接口(Interface)模式. 优点: 1.分离抽象接口及其实 ...
- mybatis由浅入深day02_8spring和mybatis整合
8 spring和mybatis整合 8.1 整合思路 需要spring通过单例方式管理SqlSessionFactory.mapper接口. spring和mybatis整合生成代理对象,使用Sql ...
- PHP-001
ThinkPHP单字母函数(快捷方法)使用总结 http://www.cnblogs.com/caicaizi/p/5173093.html
- vue中的小踩坑(01)
前言: 昨天算是使用vue2.0+element-ui做了一点小小的页面,可是源于其中遇到的问题,特地整理一下,以防自己还有其他的小伙伴们继续踩坑. 过程: 1.不知道大家有没有注意到 ...
- Eclipse+pydev解决中文显示和注释问题的方法大全
Eclipse+pydev解决中文显示和注释问题的方法大全 Eclipse的设置 window->preferences->general->editors->textedit ...