定义
【行为型】在不破坏封闭的条件下,捕获一个对象的内部状态,并在该对象之外保存状态,这样,以后就可以将该对象恢复到以前的状态。
使用场景
- 需要保存一个对象在某一时刻的状态或部分状态。
- 如果要用一个接口来让其他对象得到这个状态,将会暴露对象的实现细节,并破坏对象的封装性。一个对象不希望外界直接访问它的内部状态,便可以通过 中间对象 来间接访问其内部状态。
角色
- Originator: 负责创建备忘录 Memo,可以记录、恢复自身的内部状态。同时 Originator 还可以根据需要决定 Memo 存储自身的哪些内部状态。
- Memo:备忘录。用于存储 Originator 内部状态,并且可以防止 Originator 以外的对象访问 Memo。
- Caretaker:存储备忘录。但不能对 Memo 的内容进行操作和访问,只能够将 Memo 传递给其他对象。
实现方式
背景:打游戏,存档。第二次进入游戏,从之前保存的位置开始继续玩。
解决方案:备忘录模式
Originator
// 游戏(仙剑奇侠传)
public class LegendOfSword {
private int mCheckPoint = 1;
private int mLifeValue = 100;
private String mWeapon = "木剑";
// 玩游戏,通关
public void play() {
System.out.println("玩游戏中。。");
mLifeValue -= 20;
System.out.println("成功过关!!");
mCheckPoint++;
System.out.println("到达" + String.format("第%d关", mCheckPoint));
}
// 退出游戏
public void quit() {
System.out.println("退出游戏前属性值:" + this.toString());
System.out.println("退出游戏");
}
// 创建备忘录 Memo
public Memo createMemo() {
Memo memo = new Memo();
memo.checkPoint = mCheckPoint;
memo.lifeValue = mLifeValue;
memo.weapon = mWeapon;
return memo;
}
// 恢复游戏
public void restoreGame(Memo memo) {
this.mCheckPoint = memo.checkPoint;
this.mLifeValue = memo.lifeValue;
this.mWeapon = weapon;
System.out.println("恢复后的游戏属性值:" + this.toString());
}
@Override
public String toString() {
return "LegendOfSword [关卡:" + mCheckPoint + ", 生命值:" + mLifeValue + ", 武器:" + mWeapon + "]";
}
}
Memo
// 备忘录类(实体类,保存 Originator 的内部状态相关字段)
public class Memo {
public int checkPoint;
public int lifeValue;
public String weapon;
}
Caretaker
// 管理备忘录
public class Caretaker {
Memo memo; // 备忘录(注入备忘录引用)
// 存档
public void archive(Memo memo) {
this.memo = memo;
}
// 获取存档
public Memo getMemo() {
return this.memo;
}
}
客户端测试
public class ClientTest {
public static void main(String[] args) {
// 构建游戏对象
LegendOfSword game = new LegendOfSword();
// 打游戏
game.play();
// 构建备忘录管理对象
Caretaker caretaker = new Caretaker();
// 存档
caretaker.archive(game.createMemo());
// 游戏退出
game.quit();
// 获取存档,恢复游戏
LegendOfSword newGame = new LegendOfSword();
newGame.restoreGame(caretaker.getMemo());
}
}
优缺点
优点
- 提供一种可恢复状态的机制,可使用户方便回到某个历史状态。
- 通过封装,使用户无需知道保存状态的细节,实现解耦。
缺点
- 消耗资源。如果备忘录存储成员过多,每一次保存和恢复都会消耗一定内存。
注意
Android 中类似 备忘录App 的相关功能可以采用该模式。
在 Android 源码中,备忘录模式的应用场景在 Activity 中的 onSaveInstanceState 和 onRestoreInstanceState 两个方法中,具体可以参见源码。
onSaveInstanceState 的触发时机如下:
- 当用户按下 Home 键时;
- 长按 Home 键,运行其他程序时;
- 按下电源键(关闭屏幕显示)时;
- 从 Activity A 启动一个新的 Activity 时;
- 屏幕方向切换时,例如从竖屏切换到横屏时;
- 电话打入等情况发生时。
总之,就是非用户主动退出 某个Activity 或 跳转到其他 Activity 时,就会触发 onSaveInstanceState(在 onStop 之前调用)。同时,onSaveInstanceState 只会保存设置了 id 的控件的状态,没有设置 id 的控件则不会保存。
网友评论