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

    备忘录模式

    备忘录模式(Memento Pattern)又称快照(Snapshot)模式或Token模式。

    1备忘录模式的定义
    备忘录模式的英文原文是:
    Without violating encapsulation, capture and externalize an object's internal state so that the object can be restored to this state later.
    意思是:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
    这样,以后就可以将该对象恢复到原先保存的状态。
    通俗的说,备忘录模式就是将一个对象进行备份,提供一种程序数据备份的方法。

    备忘录中有3个角色:
    • 发起人(Originator)角色:该角色记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据。
    • 备忘录(Memento)角色:该角色负责存储发起人角色的内部状态,在需要时提供发起人需要的内部状态数据。
    • 负责人(Caretaker)角色:该角色对备忘录角色进行管理、保存和提供备忘录。

    创建发起人角色
    Originator.java
    package com.eric.行为型模式_Part2.备忘录模式;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 发起人角色
     * @CreateTime 2020-12-11 19:25:01
     */
    public class Originator {
        //内部状态
        private String state = "";
    
        public  String getState()
        {
            return state;
        }
    
        public  void setState(String state)
        {
            this.state = state;
        }
    
        //创建备忘录
        public Memento createMemento()
        {
            return new Memento(this.state);
        }
    
        //恢复一个备忘录
        public void restoreMemento(Memento memento)
        {
            this.setState(memento.getState());
        }
    }
    创建备忘录
    Memento.java
    package com.eric.行为型模式_Part2.备忘录模式;
    
    import java.security.PublicKey;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 备忘录角色
     * @CreateTime 2020-12-11 19:30:58
     */
    public class Memento {
        //发起人内部状态
        private String state;
        //构造函数传递参数
         public Memento(String state)
         {
             this.state = state;
         }
    
        public String getState() {
            return state;
        }
    
        public void setState(String state) {
            this.state = state;
        }
    }
    创建负责人
    Caretake.java
    package com.eric.行为型模式_Part2.备忘录模式;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 负责人角色
     * @CreateTime 2020-12-11 19:33:57
     */
    public class Caretaker {
        //备忘录对象
        private Memento memento;
        public Memento getMemento(){
            return memento;
        }
    
        public  void setMemento(Memento memento)
        {
            this.memento = memento;
        }
    }
    创建测试类
    Client.java
    package com.eric.行为型模式_Part2.备忘录模式;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 测试类
     * @CreateTime 2020-12-11 19:35:30
     */
    public class Client {
        public static void main(String[] args) {
            //定义发起人
            Originator originator = new Originator();
            //定义负责人
            Caretaker caretaker = new Caretaker();
            //创建一个备忘录
            caretaker.setMemento(originator.createMemento());
            //恢复一个备忘录
            originator.restoreMemento(caretaker.getMemento());
        }
    }

    2备忘录模式的应用
    a.备忘录模式的应用场景
    • 需要保存和恢复数据的相关状态场景。
    • 提供一个可回滚的操作。
    • 需要监控副本的场景。例如,监控一个对象的属性,但是监控又不应该作为系统的主业务来调用,它只是边缘应用,及时出现监控不准、错误报警也影响不大,因此一般做法是备份一个主线程中的对象,然后由分析程序来分析。
    • 数据库连接的事务管理使用的就是备忘录模式。

    b.备忘录模式的注意事项
    • 备忘录的生命周期,备忘录创建出来就要在最近的代码中使用,要主动管理它的生命周期,建立就要使用,不使用就要立刻删除其引用,等待垃圾回收器对它的回收处理。
    • 备忘录性能。不要在频繁备份的场景中使用备忘录模式,例如,for循环中,一是控制不了备忘录建立的数量;二是大对象的建立是要消耗资源的,需要考虑系统的性能。因此,如果出现这样的代码,设计师应修改架构。

    3备忘录模式的实例
    使用备忘录模式模拟版本控制系统的工作过程。
    版本控制系统的类图
    创建文件类
    Document.java
    package com.eric.行为型模式_Part2.备忘录模式.例1;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 文件
     * @CreateTime 2020-12-11 20:16:33
     */
    public class Document {
        String content;//需要备份的状态
        String otherContent;//不需要备份的状态
    
        //保存为一个备份
        public Backup save()
        {
            System.out.println("保存备份");
            return new Backup(content);
        }
    
        //恢复为某个状态
        public void resume(Backup backup)
        {
            System.out.println("恢复备份");
            this.content = backup.content;
        }
    
        @Override
        public String toString() {
            return "内容:"+content+",其他内容:"+otherContent;
        }
    }
    创建备份类
    Backup.java
    package com.eric.行为型模式_Part2.备忘录模式.例1;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 备份
     * @CreateTime 2020-12-11 20:20:28
     */
    public class Backup {
        String content;//备份内容
        int version;//版本
    
        public Backup (String content){
            this.content = content;
        }
    }
    创建版本控制系统
    VersionSontrolSystem.java
    package com.eric.行为型模式_Part2.备忘录模式.例1;
    
    import com.sun.org.apache.bcel.internal.generic.NEW;
    import jdk.nashorn.internal.ir.ReturnNode;
    
    import java.util.LinkedList;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 版本控制系统
     * @CreateTime 2020-12-11 20:21:47
     */
    public class VersionControlSystem {
        LinkedList<Backup> backups =  new LinkedList<Backup>(); //所有备份
        int nextVersion;//下一个版本
        
        //添加备份
        public void add(Backup backup)
        {
            backup.version = ++ nextVersion;
            backups.add(backup);
        }
        
        //获取某个版本的备份
        public Backup get(int version)
        {
            for (Backup backup : backups) {
                if(backup.version == version)
                {
                    return backup;
                }
            }
            return null;
        }
    
        //获取最新版本
        public Backup getLastVersion()
        {
            return backups.getLast();
        }
    }
    创建测试类
    Client.java
    package com.eric.行为型模式_Part2.备忘录模式.例1;
    
    /**
     * @author Eric
     * @ProjectName my_design_23
     * @description 测试类
     * @CreateTime 2020-12-11 20:26:37
     */
    public class Client {
        public static void main(String[] args) {
            //创建版本控制系统vcs
            VersionControlSystem vcs = new VersionControlSystem();
            //创建一个新文件,并写入内容
            Document document = new Document();
            document.content = "		日记一则
    今天吃了一泡...";
            document.otherContent = "未完待续...";
    
            System.out.println(document);
            vcs.add(document.save());//保存备份
    
            document.content = "		日记一则
    今天吃了二泡...";
            document.otherContent = "未完待续...";
    
            System.out.println(document);
            vcs.add(document.save());//保存备份
    
            document.content = "		日记一则
    今天吃了三泡...";
            document.otherContent = "完";
    
            System.out.println(document);
            document.resume(vcs.get(1)); //恢复版本1
    
            System.out.println(document);
            document.resume(vcs.getLastVersion());//恢复最新版本
    
            System.out.println(document);
        }
    }
    测试结果
    测试结果









    只要你不停下来,慢一点也没关系。
  • 相关阅读:
    JavaScript事件冒泡简介及应用
    个人作业——软件工程实践总结&个人技术博客
    个人技术总结
    个人作业——软件测评
    寒假作业(2/2)
    寒假作业(1/2)
    gitlab-ci.yml可用关键字描述
    gitlab-Runner配置参数详解
    gitlab-ci部署实现持续集成(centos7)
    linux时间同步操作命令
  • 原文地址:https://www.cnblogs.com/zyl-0110/p/14750999.html
Copyright © 2011-2022 走看看