• JAVA【设计模式】备忘录模式


    一、定义

    在这里插入图片描述

    备忘录模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后需要的时候,能将该对象恢复到原先的状态

    二、示例:

    模拟场景:
    1、git的提交记录,不仅能查看自己的提交记录,并且还能回滚到之前的版本

    2、在⼤型互联⽹公司系统的发布上线都会记录发版的信息,包括;版本号、时间、MD5、内容信息和操作⼈。在后续上线时如果发现紧急问题,系统就会需要回滚操作,如果执⾏回滚那么也可以设置配置⽂件是否回滚。

    我们接下来就使⽤备忘录模式,模拟如何记录配置⽂件信息。实际的使⽤过程中还会将信息存放到库中进⾏保存,这⾥暂时只是使⽤内存记录

    备忘录模式

    备忘录配置文件

    package com.qf.design.behavior.memorandum;
    
    import java.util.Date;
    
    /**
     * 备忘录配置文件
     */
    public class ConfigFile {
        private String versionNo;//版本号
        private String content;//内容
        private Date  date; //日期
        private String oprator;//操作人
    
        public ConfigFile(String versionNo, String content, Date date, String oprator) {
            this.versionNo = versionNo;
            this.content = content;
            this.date = date;
            this.oprator = oprator;
        }
    
        public String getVersionNo() {
            return versionNo;
        }
    
        public void setVersionNo(String versionNo) {
            this.versionNo = versionNo;
        }
    
        public String getContent() {
            return content;
        }
    
        public void setContent(String content) {
            this.content = content;
        }
    
        public Date getDate() {
            return date;
        }
    
        public void setDate(Date date) {
            this.date = date;
        }
    
        public String getOprator() {
            return oprator;
        }
    
        public void setOprator(String oprator) {
            this.oprator = oprator;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    备忘录类

    package com.qf.design.behavior.memorandum;
    
    /**
     * 备忘录类
     */
    public class ConfigMemento {
        private ConfigFile configFile;
    
        public ConfigMemento(ConfigFile configFile){
            this.configFile=configFile;
        }
    
        public ConfigFile getConfigFile(){
            return configFile;
        }
    
        public void setConfigFile(ConfigFile configFile){
            this.configFile=configFile;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    备忘录操作人员:

    package com.qf.design.behavior.memorandum;
    
    public class ConfigOperator {
        private ConfigMemento configMemento;
        private ConfigFile configFile;
    
        public ConfigMemento getConfigMemento() {
            return configMemento;
        }
    
        public void setConfigMemento(ConfigMemento configMemento) {
            this.configMemento = configMemento;
        }
    
    
        public ConfigFile getConfigFile(){
            return configFile;
        }
    
        public void setConfigFile(ConfigFile configFile){
            this.configFile=configFile;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    管理后台

    package com.qf.design.behavior.memorandum;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class Admin {
        private int cursorinx=0;
    
        private List<ConfigMemento> configMementoList=new ArrayList<>();
    
        private Map<String,ConfigMemento> configMementoMap=new HashMap<>();
    
        public void append(ConfigMemento configMemento){
            configMementoList.add(configMemento);
            configMementoMap.put(configMemento.getConfigFile().getVersionNo(),configMemento);
            cursorinx++;
        }
    
        public ConfigMemento undo(){
            if (--cursorinx<=0){
                return configMementoList.get(0);
            }
    
            return configMementoList.get(cursorinx);
        }
    
        public ConfigMemento redo(){
            if (++cursorinx>=configMementoList.size()){
                return configMementoList.get(configMementoList.size()-1);
            }
            return configMementoList.get(cursorinx);
        }
    
        public ConfigMemento get(String version){
            ConfigMemento configMemento = configMementoMap.get(version);
            return configMemento;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    测试:ApiTest

    package com.qf.design.behavior.memorandum;
    
    import com.alibaba.fastjson.JSON;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.Date;
    
    public class ApiTest {
    
        private static Logger logger= LoggerFactory.getLogger(ApiTest.class);
        public static void main(String[] args) {
            Admin admin=new Admin();
    
            ConfigOperator configOperator=new ConfigOperator();
            ConfigFile configFile = new ConfigFile("1004001", "配置内容A版本", new Date(), "小王哥");
            ConfigMemento configMemento = new ConfigMemento(configFile);
            configOperator.setConfigFile(configFile);
            configOperator.setConfigMemento(configMemento);
            admin.append(configMemento);
    
            ConfigFile configFile1 = new ConfigFile("1004002", "配置内容B版本", new Date(), "小王哥");
            ConfigMemento configMemento1 = new ConfigMemento(configFile1);
            configOperator.setConfigFile(configFile1);
            configOperator.setConfigMemento(configMemento1);
            admin.append(configMemento1);
    
            ConfigFile configFile2 = new ConfigFile("10040013", "配置内容C版本", new Date(), "小王哥");
            ConfigMemento configMemento2 = new ConfigMemento(configFile2);
            configOperator.setConfigFile(configFile2);
            configOperator.setConfigMemento(configMemento2);
            admin.append(configMemento2);
    
            ConfigFile configFile3 = new ConfigFile("1004004", "配置内容D版本", new Date(), "小王哥");
            ConfigMemento configMemento3 = new ConfigMemento(configFile3);
            configOperator.setConfigFile(configFile3);
            configOperator.setConfigMemento(configMemento3);
            admin.append(configMemento3);
    
            ConfigMemento redo = admin.undo();
            ConfigFile configFile4 = redo.getConfigFile();
            logger.info("第一次版本回滚{}", JSON.toJSONString(configFile4));
    
            ConfigMemento redo2 = admin.undo();
            ConfigFile configFile5 = redo2.getConfigFile();
            logger.info("第二次版本回滚{}", JSON.toJSONString(configFile5));
    
            ConfigMemento redo3 = admin.redo();
            ConfigFile configFile6 = redo3.getConfigFile();
            logger.info("当前版本{}", JSON.toJSONString(configFile6));
    
            ConfigMemento configMemento4 = admin.get("1004004");
            ConfigFile configFile7 = configMemento4.getConfigFile();
            logger.info("查看版本1004004{}", JSON.toJSONString(configFile7));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    在这里插入图片描述
    总结:
    此种设计模式的⽅式可以满⾜在不破坏原有属性类的基础上,扩充了备忘录的功能。虽然和我们平时使⽤的思路是⼀样的,但在具体实现上还可以细细品味,这样的⽅式在⼀些源码中也有所体现。

    在以上的实现中我们是将配置模拟存放到内存中,如果关机了会导致配置信息丢失,因为在⼀些真实的场景⾥还是需要存放到数据库中。那么此种存放到内存中进⾏回复的场景也不是没有,⽐Photoshop、运营⼈员操作ERP配置活动,那么也就是即时性的⼀般不需要存放到库中进⾏恢复。另外如果是使⽤内存⽅式存放备忘录,需要考虑存储问题,避免造成内存⼤量消耗。

  • 相关阅读:
    如何在不带备份的情况下恢复 Android 手机照片?
    傻瓜式Java操作MySQL数据库备份
    【python海洋专题十六】对大陆周边的数据进行临近插值
    4. algorithm
    NLP模型笔记2022-33:Sentence-BERT STS模型列表与预训练方法
    什么是线程?为什么需要线程?和进程的区别?
    Kafka 3.3.1 Kraft 多端口协议搭建
    Lodash初识
    TCP协议:如何保证页面文件能被完整送达浏览器?
    适合小企业的CRM有哪五点要求
  • 原文地址:https://blog.csdn.net/cativen/article/details/126265720