备忘录模式(行为型)

备忘录模式(Memento Pattern),又称为快照(snapshot)模式,或Token模式;
备忘录模式定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存该状态.这样,以后就可以将该对象恢复到原先的状态.
如:联机事务处理时,需要对原子操作前的状态备份一下,以便原子操作失败时能回滚,因此需要用到备忘录模式;


实例:系统需要对一个文档对象的不同状态进行备份,以便后期可以回退,如何设计?

因为文档对象存在很多不需要备份的属性,如文档大小,文档名称等很多信息,所以我们有必要新建一个类(快照类)专门表示一次备份的信息.然后使用另外一个类专门管理所有的快照对象.如图(document对象提供产生快照对象的方法,因此是依赖关系,一个版本系统中保存多个快照对象):

这里写图片描述

Document文档类:

package com.shusheng.pattern.memento;

//重要文档
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("恢复备份");
        content = backup.content;
    }

    @Override
    public String toString() {
        return "content : " + content + ", otherContent: " + otherContent;
    }
}

Backup快照类:

package com.shusheng.pattern.memento;
//备份对象
public class Backup {

    String content;//备份内容
    int version;//版本

    public Backup(String content) {
        this.content = content;
    }
}

VersionControlSystem版本控制系统,专门管理快照对象:

package com.shusheng.pattern.memento;

import java.util.LinkedList;
//版本控制系统
public class VersionControlSystem {

    LinkedList<Backup> backups =  new LinkedList<>();//使用链表管理快照对象
    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();
    }
}

Test测试类:

package com.shusheng.pattern.memento;

public class Test {
    public static void main(String[] args) {

        VersionControlSystem vcs = new VersionControlSystem();
        Document document = new Document();
        document.content = "content1";
        document.otherContent = "otherContent1";
        System.out.println(document); 
        vcs.add(document.save());//保存一个快照对象,document.save()生成快照对象
        document.content="content2";
        document.otherContent = "otherContent2";
        System.out.println(document);
        vcs.add(document.save());//保存一个快照对象
        document.content = "content3";
        document.otherContent = "otherContent3";
        System.out.println(document);
        vcs.add(document.save());//保存一个快照对象

        System.out.println("版本控制系统的版本数量:"+vcs.backups.size());
        System.out.println("------------------------");
        document.resume(vcs.get(1));//回退到版本1
        System.out.println(document);
        document.resume(vcs.getLastVersion());//回退到最新版本
        System.out.println(document);
    }
}

结果分析:
首先连续向版本控制系统添加了三个快照对象(otherContent信息是不在备份范围内的).
此时版本控制系统的快照数量为3;
恢复备份时因为otherContent没在备份范围内,所以信息不回退,而content的信息回退到了第一个版本.
然后又让文档对象回归到最新版(第三版);
这里写图片描述


备忘录模式使用场景:
1. 需要保存和恢复数据的相关状态场景.
2. 提供一个可回滚的操作.
3. 需要监控副本的场景.
4. 数据库链接的事务管理(使用的就是备忘录模式)


备忘录模式的注意事项 :
1. 备忘录的生命周期:备忘录对象创建出来就是再最近的代码中使用,要主动管理它的生命周期,建立就要使用,不使用就要立刻删除其引用,等待垃圾回收器对它的回收处理,避免占用内存;
2. 备忘录的性能: 不要在频繁建立备份的场景中使用备忘录模式,例如:for循环.一是控制不了备忘录建立的数量,二是大对象的建立时要消耗资源的,需要考虑系统的性能.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值