zoukankan      html  css  js  c++  java
  • 备忘录模式-Memento

    备忘录模式用来恢复一个对象的状态到以前的状态。 通俗的说,就是把一个类的属性临时的保存在另一个地方,并提供一个接口可以还原,比较适用的场景是系统升级,代码回滚。

    一、类图

    备忘录模式包含以下几个角色:

    • Originator(原发器):它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。
    • Memento(备忘录):存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,原发器的设计在不同的编程语言中实现机制会有所不同。
    • Caretaker(负责人):负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。

    二、示例

    考虑平时玩的通关游戏,每走一步时步数都加一,遇到道具可以快速走几步,或者减几步。用备忘录模式的思想来实现这个逻辑。

    游戏类:

    class Game {
    
        /**
         * 玩家走的步数
         */
        private int playerStep;
    
        /**
         * 备份游戏
         */
        public GameMemento createGameMemento() {
            return new GameMemento(playerStep);
        }
    
        /**
         * 开始玩游戏
         */
        public void play() {
            playerStep = 0;
        }
    
        /**
         * 恢复备份
         */
        public void restore(GameMemento gameMemento) {
            this.playerStep = gameMemento.getPlayerSteps();
        }
    }

    备份

    /**
     * 备份
     */
    class GameMemento {
        /**
         * 步数
         */
        private int playerSteps;
    
        /**
         * 备份步数
         */
        public GameMemento(int playerSteps) {
            this.playerSteps = playerSteps;
        }
    }

    备份信息管理类

    /**
     * 备份信息管理类
     */
    public class Caretaker {
        /**
         * 备份
         */
        private GameMemento gameMemento;
    
        /**
         * 恢复备份
         */
        public GameMemento retrieveMemento() {
            return this.gameMemento;
        }
    
        /**
         * 保存备份
         */
        public void saveMemento(GameMemento gameMemento) {
            this.gameMemento = gameMemento;
        }
    }

    测试

    public class Player {
    
        public static void main(String[] args) {
    
            Game game = new Game();
            System.out.println("游戏开始,捡到滑板,前进10步");
            game.setPlayerStep(10);
            //备份当前状态
            System.out.println("备份当前状态");
            GameMemento gameMemento = game.createGameMemento();
    
            Caretaker caretaker = new Caretaker();
    
            caretaker.saveMemento(gameMemento);
            System.out.println("备份完成");
            game.play();
            System.out.println("踩到便便了,当前步数为:" + game.getPlayerStep());
            System.out.println("还原到之前一步");
            game.restore(caretaker.retrieveMemento());
    
            System.out.println("恢复完成,当前玩家步数是:" + game.getPlayerStep());
    
        }
    }

    三、备忘录模式的优缺点和适用场景

    优点:

    当发起人角色中的状态改变时,有可能这是个错误的改变,我们使用备忘录模式就可以把这个错误的改变还原。

    备份的状态是保存在发起人角色之外的,这样,发起人角色就不需要对各个备份的状态进行管理。

    缺点:

    在实际应用中,备忘录模式都是多状态和多备份的,发起人角色的状态需要存储到备忘录对象中,对资源的消耗是比较严重的。

    ……更多设计模式的内容,可以访问Refactoring.Guru

  • 相关阅读:
    制作Autorun的CD
    Sybase ASE MDA tables 装不上怎么办?
    对于TStringList.Find函数,我有话要说
    HH.exe CHM Operator Command.
    Delphi 7的一些常用的快捷键
    Explain Plan
    在Delphi中的Log
    subst windows下实用的磁盘映射工具
    Excel 2007 如何冻结多行&多列
    LinqToDataTable[转]
  • 原文地址:https://www.cnblogs.com/rouqinglangzi/p/11760953.html
Copyright © 2011-2022 走看看