zoukankan      html  css  js  c++  java
  • Java设计模式学习记录-备忘录模式

    前言

    这次要介绍的是备忘录模式,也是行为模式的一种 。现在人们的智能手机上都会有备忘录这样一个功能,大家也都会用,就是为了记住某件事情,防止以后自己忘记了。那么备忘录模式又是什么样子的呢?是不是和手机上的备忘录一样呢?下面来介绍一下。

    备忘录模式 

    概念介绍

    备忘录模式是指在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。简单的来说就是平时玩的通关游戏,第一次前进了5步,第二次前进时踩到便便了,然后要回到之前的进度。例如下图结构:

     

    举例

    我们还是用一个小例子来简单介绍一下备忘录模式,在玩一个步骤游戏时,每走一步时步数都加一,遇到道具可以快速走几步,或者减几步。用备忘录模式的思想来实现这个逻辑,就是如下代码。

    游戏类

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

    备份

    /**
     * 备份
     */
    @Getter
    public class GameMemento {
        /** 步数 */
        private int playerSteps;
    
        /**
         * 备份步数
         * @param 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());
    
        }
    
    }

    运行结果

    游戏开始,捡到滑板,前进10步
    备份当前状态
    备份完成
    踩到便便了,当前步数为:0
    还原到之前一步
    恢复完成,当前玩家步数是:10

    上面的这个例子使用了lombok插件的注解例如:@Getterhe@Data所以少写了getter和setter方法。看完了这个小例子,大概应该知道备忘录模式是个什么逻辑了吧,有点类似咱们平时知道的事务回滚的机制。下面还是分析一下,备忘录模式都是由哪些部分组成的。

    备忘录模式结构

    结构图如下

    备忘录模式的构成角色如下所示。

    原发器类(Originator):创建一个备忘录对象,使用备忘录存储它的内部状态。

    负责人类(CareTaker):负责保存好备忘录对象,不能检查或操作备忘录的内容。

    备忘录类(Memento):将原发器的内部状态存储起来,原发器根据需要决定备忘录存储原发器的哪些内部状态。

    总结

    优点

    1、它提供了一种状态恢复的实现机制,使得用户可以方便地回到一个特定的历史步骤,当新的状态无效或者存在问题时,可以使用暂时存储起来的备忘录将状态复原。

    2、备忘录实现了对信息的封装,一个备忘录对象是一种原发器对象状态的表示,不会被其他代码所改动。备忘录保存了原发器的状态,采用列表、堆栈等集合来存储备忘录对象可以实现多次撤销操作。

    缺点 

    资源消耗过大,如果需要保存的原发器类的成员变量太多,就不可避免需要占用大量的存储空间,每保存一次对象的状态都需要消耗一定的系统资源。

    适用场景

    1、保存一个对象在某一个时刻的全部状态或部分状态,这样以后需要时它能够恢复到先前的状态,实现撤销操作。

    2、防止外界对象破坏一个对象历史状态的封装性,避免将对象历史状态的实现细节暴露给外界对象。

    想了解更多的设计模式请查看Java设计模式学习记录-GoF设计模式概述

  • 相关阅读:
    C#创建线程
    Halcon算子
    二叉树的层次遍历
    反转单链表
    “开-闭”原则 (Open-Closed principle, OCP)
    CSUOJ1867 John and Health rate
    LOCAL_MODULE_TAGS
    void * kmalloc(size_t size, int flags)
    printk(Loglevels string)
    container_of宏定义解析
  • 原文地址:https://www.cnblogs.com/jimoer/p/9537997.html
Copyright © 2011-2022 走看看