备忘录模式

定义

【行为型】在不破坏封闭的条件下,捕获一个对象的内部状态,并在该对象之外保存状态,这样,以后就可以将该对象恢复到以前的状态。

使用场景

  • 需要保存一个对象在某一时刻的状态或部分状态。
  • 如果要用一个接口来让其他对象得到这个状态,将会暴露对象的实现细节,并破坏对象的封装性。一个对象不希望外界直接访问它的内部状态,便可以通过 中间对象 来间接访问其内部状态。

角色

  • 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 的控件则不会保存。

你可能感兴趣的:(备忘录模式)