Java设计模式之从[暗黑破坏神存档点]分析备忘录(Memento)模式
在大部分游戏中,都有一个“存档点”的概念。比如,在挑战boss前,游戏会在某个地方存档,假设玩家挑战boss失败,则会从这个存档点開始又一次游戏。因此,我们能够将这个“存档点”当成是一个备忘录,我们将此时玩家全部的状态保存下来,以便之后的读取。
备忘录模式正是如此,它在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就能够将该对象恢复到原先的保存状态了。
一个简单的样例,如果玩家在暗黑破坏神中准备挑战Boss巴尔,玩家携带了10瓶药剂,而且在巴尔的门前“世界之石”存了档,玩家在挑战Boss时使用了1瓶药剂,后来挑战失败了,于是他又一次读档,再次回到了世界之石,此时他身上携带的药剂数量仍然应该为10瓶。
详细的代码例如以下:
interface IMemento{
} class CharacterOriginator{
private int potion;
private String position;
public void move(String place){
position = place;
}
public void usePotion(){
potion --;
}
public int getPotion() {
return potion;
}
private void setPotion(int potion) {
this.potion = potion;
}
public String getPosition() {
return position;
}
private void setPosition(String position) {
this.position = position;
}
public IMemento createMemento(){
return new Memento(potion, position);
}
public void restoreMemento(IMemento memento){
setPotion(((Memento)memento).getPotion());
setPosition(((Memento)memento).getPosition());
}
public CharacterOriginator(int potion, String position){
this.potion = potion;
this.position = position;
}
private class Memento implements IMemento{
private int potion;
String position;
public Memento(int potion, String position){
this.potion = potion;
this.position = position;
}
public int getPotion() {
return potion;
}
public String getPosition() {
return position;
} }
} class Caretaker{
IMemento memento;
public IMemento getMemento() {
return memento;
}
public void setMemento(IMemento memento) {
this.memento = memento;
}
} class Memento
{
public static void main(String[] args) {
CharacterOriginator player = new CharacterOriginator(10, "世界之石");
Caretaker caretaker = new Caretaker();
caretaker.setMemento(player.createMemento());
System.out.printf("玩家携带的药剂:%d,所在位置:%s\n", player.getPotion(), player.getPosition());
player.usePotion();
player.move("巴尔的宫殿");
//玩家挑战失败后又一次读档
System.out.printf("玩家携带的药剂:%d,所在位置:%s\n", player.getPotion(), player.getPosition());
player.restoreMemento(caretaker.getMemento());
System.out.printf("玩家携带的药剂:%d,所在位置:%s\n", player.getPotion(), player.getPosition());
}
如今来分析一下上面的代码,并同一时候解说备忘录模式。备忘录模式有3个參与者:Originator——负责创建备忘录、还原备忘录,人物的各种状态都在此,如样例中的CharacterOriginator。Memento——备忘录,它表示须要存储哪些数据,Originator通过须要在备忘录上取数据。在上例中,Memento为Originator的一个内部类。Caretaker——负责保存、获取Memento。为了不暴露Memento的内部方法(我们觉得,Memento的内部方法仅仅能由CharacterOriginator获取),我们让Memento继承了一个空接口IMemento,因此通过Caretaker获得的备忘录均是IMemento类型的,我们无法对它做不论什么事情,可是能够把它传给CharacterOriginator,然后Originator的restoreMemento能够把IMemento类型强制转换为Memento类型。请注意,因为Memento为内部私有类,因此除了CharacterOriginator外,其余的类无法调用Memento的方法,这也就是我们说的“不暴露Memento内部方法”。restoreMemento中清晰写明了应该还原哪些状态,在这里就不进行详解了。
最后我们看看main方法。首先实例化了一个玩家(player),他有10瓶药水,位于世界之石;随后他进入了巴尔的宫殿,并用掉了一瓶药水;最后,他因为挑战失败而恢复到了曾经的存档点——拥有10瓶药水,位于世界之石。因此,程序执行的结果为:
玩家携带的药剂:10,所在位置:世界之石
玩家携带的药剂:9,所在位置:巴尔的宫殿
玩家携带的药剂:10,所在位置:世界之石
以上就是备忘录模式的说明,希望能对大家有所帮助。
Java设计模式之从[暗黑破坏神存档点]分析备忘录(Memento)模式的更多相关文章
- JAVA设计模式-动态代理(Proxy)源码分析
在文章:JAVA设计模式-动态代理(Proxy)示例及说明中,为动态代理设计模式举了一个小小的例子,那么这篇文章就来分析一下源码的实现. 一,Proxy.newProxyInstance方法 @Cal ...
- Java并发系列[2]----AbstractQueuedSynchronizer源码分析之独占模式
在上一篇<Java并发系列[1]----AbstractQueuedSynchronizer源码分析之概要分析>中我们介绍了AbstractQueuedSynchronizer基本的一些概 ...
- Java并发系列[3]----AbstractQueuedSynchronizer源码分析之共享模式
通过上一篇的分析,我们知道了独占模式获取锁有三种方式,分别是不响应线程中断获取,响应线程中断获取,设置超时时间获取.在共享模式下获取锁的方式也是这三种,而且基本上都是大同小异,我们搞清楚了一种就能很快 ...
- Java设计模式六大原则之场景应用分析
定义:不要存在多于一个导致类变更的原因. 通俗的说.即一个类仅仅负责一项职责. 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而须要改动类T时,有可能会导致原本执行正 ...
- 【java设计模式】之 抽象工厂(Abstract Factory)模式
1. 女娲的失误 上一节学习了工厂模式,女娲运用了该模式成功创建了三个人种,可是问题来了,她发现没有性别--这失误也忒大了点吧--竟然没有性别,那岂不是--无奈,只好抹掉重来了,于是所有人都被消灭掉了 ...
- Java设计模式从精通到入门五 抽象工厂方法模式
定义 抽象工厂类为创建一组相关和相互依赖的对象提供一组接口,而无需指定一个具体的类. 这里我得把工厂方法模式得定义拿出来做一下比较:定义一个创建对象的接口,由子类决定实例化哪一个类.工厂方法是一个 ...
- C++设计模式实现--备忘录(Memento)模式
一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态.并在该对象之外保存这个状态. 这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比較适用于功 ...
- 设计模式C++描述----17.备忘录(Memento)模式
一. 备忘录模式 定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态. 结构图: 使用范围: Memento 模式比较适用于功能 ...
- JAVA设计模式-动态代理(Proxy)示例及说明
在Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析文章的最后部分,我们提到了动态代理的概念,下面我们就简单了解一下动态代理. 一,概念 代理设计模式的目的就是在不直接操作对象的前 ...
随机推荐
- 随时查看源码的网站---http://www.sooset.com/
由于工作需要经常要在Windows平台下参阅linux源码,以前都用http://lxr.linux.no/来浏览源码(如下图所示),最近发现sooset来浏览更方便,所以介绍给大家分享. 650) ...
- 【arc062e】Building Cubes with AtCoDeer
Description STL有n块瓷砖,编号从1到n,并且将这个编号写在瓷砖的正中央: 瓷砖的四个角上分别有四种颜色(可能相等可能不相等),并且用Ci,0,Ci,1,Ci,2,Ci,3分别表示左上. ...
- [D3] Draw a basic US d3-geo map
Install: npm install --save d3 d3-geo topojson Code: import React, {Component} from 'react'; import ...
- 7.3 GROUP BY的“新”功能
7.3 GROUP BY的"新"功能正在更新内容,请稍后
- 文件上传流式处理commons-fileupload
1. 从请求中获取MultipartFile @RequestMapping(value="/upload", method=RequestMethod.POST) public ...
- React render return 空行问题
Uncaught Invariant Violation: App.render(): A valid React element (or null) must be returned. You ma ...
- Appium_Java_API
1. driver.findElement(MobileBy.AndroidUIAutomator("邀请")).click();2. driver.findElementById ...
- serialport串口通讯
在.NET Framework 2.0中提供了SerialPort类,该类主要实现串口数据通信 = System.IO.Ports.SerialPort.GetPortNames();获取电脑有哪几个 ...
- SQL_wm_concat函数实验:实现字段合并
原创作品,出自 "深蓝的blog" 博客.欢迎转载.转载时请务必注明下面出处,否则追究版权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlo ...
- Netty系列之Netty可靠性分析--转载
原文地址:http://www.infoq.com/cn/articles/netty-reliability 1. 背景 1.1. 宕机的代价 1.1.1. 电信行业 毕马威国际(KPMG Inte ...