美文网首页
备忘录模式

备忘录模式

作者: FredWhite | 来源:发表于2019-11-10 23:38 被阅读0次

    定义

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

    使用场景

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

    角色

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

    相关文章

      网友评论

          本文标题:备忘录模式

          本文链接:https://www.haomeiwen.com/subject/fjzabctx.html