您的位置:首页 > 其它

备忘录模式(行为型)

2016-06-16 11:21 183 查看
备忘录模式(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循环.一是控制不了备忘录建立的数量,二是大对象的建立时要消耗资源的,需要考虑系统的性能.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息