什么是备忘录模式
在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存该状态,以后可用来恢复对象保存的状态。备忘录模式就像我们对于现阶段所做的备份,以后如果用得到就可以根据这个备份进行操作。比如windows系统的系统恢复点的创建,如我我们害怕系统突然的崩溃掉,就可以创建一个恢复点,万一系统真的崩溃了,我们就根据这个恢复点来进行系统恢复。
备忘录模式适用场景
- 需要保存某个对象某个时刻的状态
- 一个对象不希望外界直接访问其内部状态,通过中间对象间接访问其内部状态
备忘录模式用例
我们玩一个单机游戏需要在退出的时候存档,下次玩的时候可以根据上次的存档来继续玩,这里用的就是一个简单的备忘录模式。游戏类Game主要包含用户名字,升级、退出、创建关卡点等操作。备忘录类只包含两个变量只存储Game对象的字段,真正实现备忘的是CareTaker类。
UML类图
游戏类Game:
public class Game {
private String mName = null;
private int mSteps = 1;
public String getmName() {
return mName;
}
public void setmName(String mName) {
this.mName = mName;
}
//玩游戏,模仿升级到第十级
public void playGame(int steps){
System.out.println("正在打游戏,当前"+String.format("第%d关", mSteps));
for(;;){
mSteps += 1;
System.out.println("打怪升级啦,玩到了"+String.format("第%d关", mSteps));
if(mSteps == steps)
break;
}
}
//退出游戏
public void quitGame(){
System.out.println("退出游戏,正在备份。。。");
}
//备忘录创建
public Memento createMemento(){
Memento memento = new Memento();
memento.mName = mName;
memento.mSteps = mSteps;
return memento;
}
//备忘录恢复
public void restore(Memento memento){
this.mName = memento.mName;
this.mSteps = memento.mSteps;
System.out.println(mName+",您上次玩到的关卡为"+mSteps);
}
}
Memento类:
public class Memento {
public String mName;
public int mSteps;
}
CareTaker类:
public class CareTaker {
Memento mMemento;
/**
* 存档
*/
public void archive(Memento memento){
this.mMemento = memento;
}
/**
* 获取存档
*/
public Memento getMemento(){
return mMemento;
}
}
主类调用:
public class Test {
public static void main(String[] args) {
//新建游戏
Game mGame = new Game();
mGame.setmName("小明");
//玩游戏,参数模仿玩到的关数
mGame.playGame(5);
//创建存档
CareTaker caretaker = new CareTaker();
caretaker.archive(mGame.createMemento());
//退出游戏
mGame.quitGame();
//根据存档新建游戏
Game mGame2 = new Game();
mGame2.restore(caretaker.getMemento());
}
}
运行结果:
正在打游戏,当前第1关
打怪升级啦,玩到了第2关
打怪升级啦,玩到了第3关
打怪升级啦,玩到了第4关
打怪升级啦,玩到了第5关
退出游戏,正在备份。。。
小明,您上次玩到的关卡为5
总结:
Game类是需要存储数据的对象,但我们存储的时候并没有直接操作Game对象,而是通过Memento对象对Game对象进行存储,最后通过CareTaker对象实现保存。防止了外部直接对Game对象访问,使得代码结构明了。备忘录模式强调的是不破坏封闭,来对一个对象进行存储。
优点:实现封装,用户无需关心实现细节。给用户提供可恢复状态的保存机制,如果没有这个机制,我们玩游戏玩到一半,退出后又要重头再来岂不是很无语。
缺点:消耗资源,类成员如果很多,比如一个游戏要保存花草树木等等很多状态,那每次保存要消耗的资源可就比较多了。