Java设计模式-备忘录模式(Memento Pattern)
目录
- 什么是备忘录模式
- 备忘录模式的实现
- JavaSE备忘录模式的应用
- Struts2备忘录模式的应用
备忘录模式的核心是对象状态的保存与恢复
一、什么是备忘录模式
备忘录模式(Memento): 在不破环封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。以后就可将该对象恢复到原先保存的状态。
开发中常见的应用场景 :
- 棋类游戏中的,悔棋
- 普通软件中的,撤销操作
- 数据库软件中的,事务管理中的,回滚操作
- Photoshop软件中的,历史记录
- 原发器(Originator)类可以生成自身状态的快照,也可以在需要时通过快照恢复自身状态。
- 备忘录(Memento)是原发器状态快照的值对象(value object)。通常做法是将备忘录设为不可变的,并通过构造函数一次性传递数据。
- 负责人(Caretaker)仅知道“何时”和“为何”捕捉原发器的状态,以及何时恢复状态。 负责人通过保存备忘录栈来记录原发器的历史状态。当原发器需要回溯历史状态时,负责人将从栈中获取最顶部的备忘录,并将其传递给原发器的恢复(restoration)方法。
- 在该实现方法中,备忘录类将被嵌套在原发器中。这样原发器就可访问备忘录的成员变量和方法,即使这些方法被声明为私有。另一方面,负责人对于备忘录的成员变量和方法的访问权限非常有限:它们只能在栈中保存备忘录,而不能修改其状态。
二、备忘录模式的实现
模拟VMware虚拟机快照的功能,可以还原到某个时间点,类图就是上面讲的类图
package org.Memento.version1;
import java.util.HashMap;
import java.util.Map;
class Originator{
// 安装了哪些软件
private String soft;
// 创建了哪些文件
private String file;
public Originator(String file, String soft){
setSoft(soft);
setFile(file);
}
// 创建快照
public IMemento createMemento(){
return new Memento(this);
}
// 恢复快照
public void restoreMemento(IMemento m){
setFile(((Memento)m).getFile());
setSoft(((Memento)m).getSoft());
}
public String getSoft() {
return soft;
}
public void setSoft(String soft) {
this.soft = soft;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
@Override
public String toString() {
String nowStatus = "当前的快照状态为:安装了软件:" + getSoft() + "创建了文件:" + getFile();
return nowStatus;
}
}
interface IMemento{
}
class Memento implements IMemento{
// 安装了哪些软件
private String soft;
// 创建了哪些文件
private String file;
public Memento(Originator o){
this.soft = o.getSoft();
this.file = o.getFile();
}
public String getSoft() {
return soft;
}
public void setSoft(String soft) {
this.soft = soft;
}
public String getFile() {
return file;
}
public void setFile(String file) {
this.file = file;
}
}
class Caretaker{
// 用于保存历史快照
private Map<String,IMemento> ms = new HashMap<>();
public void addMemento(String id, IMemento m){
ms.put(id,m);
}
public IMemento getMemento(String id){
return ms.get(id);
}
}
public class Test {
public static void main(String[] args) {
Originator o = new Originator("NULL","NULL");
Caretaker caretaker = new Caretaker();
caretaker.addMemento("1",o.createMemento());
System.out.println(o.toString());
System.out.println("--------------------------------");
o.setSoft("SSH");
caretaker.addMemento("2",o.createMemento());
System.out.println(o.toString());
System.out.println("--------------------------------");
o.restoreMemento(caretaker.getMemento("1"));
System.out.println("开始恢复快照");
System.out.println(o.toString());
}
}
// 运行结果
当前的快照状态为:安装了软件:NULL创建了文件:NULL
--------------------------------
当前的快照状态为:安装了软件:SSH创建了文件:NULL
--------------------------------
开始恢复快照
当前的快照状态为:安装了软件:NULL创建了文件:NULL
三、JavaSE备忘录模式的应用
备忘录模式的核心是对象状态的保存,很容易联想到序列化与反序列化,序列化是保存状态,反序列化是恢复状态,恰好可以模拟备忘录模式,对应类为:java.io.Serializable
四、Struts2备忘录模式的应用
暂未发现,如果读者有发现,请联系我添加,谢谢