作者持续关注 WPS二次开发专题系列,持续为大家带来更多有价值的WPS开发技术细节,如果能够帮助到您,请帮忙来个一键三连,更多问题请联系我(QQ:250325397)
目录
[(1) 优点](#(1) 优点)
[(2) 缺点](#(2) 缺点)
定义
备忘录(Memento)模式:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。该模式又叫快照模式。
特点
在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
使用场景
-
- 打游戏时的存档。
- Windows 、WPS里的 ctrl + z。
- 浏览器 中的后退。
- 数据库的事务管理。
优缺点
(1) 优点
-
- 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态
- 实现了信息的封装,使得用户不需要关心状态的保存细节
(2) 缺点
-
- 消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。
模式结构
-
- 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。
- 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。
- 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。
具体实现
抽象类
/**
* 文本编辑器
*/
public class EditText {
private String text;
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
/**
* 保存
* @return 保存后的快照
*/
public Snapshot save() {
System.out.println("edit text save, text:" + this.text);
return new Snapshot(this.text);
}
/**
* 根据快照进行恢复
*/
public void restore(Snapshot snapshot) {
if (snapshot == null) {
System.out.println("edit text restore fail, snapshot is empty");
return;
}
this.text = snapshot.getText();
System.out.println("edit text restore, new text:" + this.text);
}
@Override
public String toString() {
return "EditText{" +
"text='" + text + '\'' +
'}';
}
}
/**
* 存储状态的快照
*/
public class Snapshot {
private String text;
public Snapshot(String text) {
this.text = text;
}
public String getText() {
return text;
}
}
/**
* 快照管理器
*/
public class CareTaker {
private Stack<Snapshot> snapshotStack = new Stack<>();
/**
* 添加一个快照
*/
public void addSnapshot(Snapshot snapshot) {
snapshotStack.push(snapshot);
}
/**
* 获取一个快照
*/
public Snapshot obtainSnapshot() {
if (snapshotStack.isEmpty()) {
return null;
}
return snapshotStack.pop();
}
}
具体使用
public class App {
public static void main(String[] args) {
//初始化
EditText editText = new EditText();
editText.setText("abc");
//保存
Snapshot snapshot = editText.save();
System.out.println("edit text #1:" + editText);
//添加保存快照
CareTaker careTaker = new CareTaker();
careTaker.addSnapshot(snapshot);
System.out.println();
//内容变更
editText.setText("def");
System.out.println("edit text #2:" + editText);
System.out.println();
//回退2
editText.restore(careTaker.obtainSnapshot());
System.out.println("edit text restore #1:" + editText);
}
}
实际应用
- 各种工具类应用中的undo、redo功能实现