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 = "\t\t日记一则\n今天吃了一泡...";
        document.otherContent = "未完待续...";

        System.out.println(document);
        vcs.add(document.save());//保存备份

        document.content = "\t\t日记一则\n今天吃了二泡...";
        document.otherContent = "未完待续...";

        System.out.println(document);
        vcs.add(document.save());//保存备份

        document.content = "\t\t日记一则\n今天吃了三泡...";
        document.otherContent = "完";

        System.out.println(document);
        document.resume(vcs.get(1)); //恢复版本1

        System.out.println(document);
        document.resume(vcs.getLastVersion());//恢复最新版本

        System.out.println(document);
    }
}
测试结果
测试结果









posted @ 2021-05-10 14:35  喵酱张-Eric  阅读(80)  评论(0编辑  收藏  举报